Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1cc3c019e6 | |||
| 319aa558a5 |
+2
-7
@@ -25,7 +25,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v36"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v35"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
|
||||
.only-default:
|
||||
@@ -88,7 +88,7 @@ fedora-x86_64:
|
||||
- meson compile -C _build
|
||||
- meson install -C _build
|
||||
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
|
||||
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
||||
- meson compile -C _build_hello
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build waylandgles
|
||||
@@ -156,11 +156,6 @@ msys2-mingw64:
|
||||
variables:
|
||||
MSYSTEM: "MINGW64"
|
||||
CHERE_INVOKING: "yes"
|
||||
artifacts:
|
||||
when: always
|
||||
expose_as: 'Windows_DLL_MSYS2_64_bit_toolchain'
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
|
||||
|
||||
macos:
|
||||
extends: .only-default
|
||||
|
||||
@@ -95,8 +95,6 @@ RUN dnf -y install \
|
||||
weston-libs \
|
||||
which \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf install -y 'dnf-command(builddep)' \
|
||||
&& dnf builddep -y wayland \
|
||||
&& dnf clean all
|
||||
|
||||
# Enable sudo for wheel users
|
||||
|
||||
@@ -31,8 +31,7 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
@@ -73,5 +72,3 @@ unset CCACHE_DISABLE
|
||||
|
||||
ninja -C _build
|
||||
ccache --show-stats
|
||||
|
||||
tar zcf _build/gtkdll.tar.gz _build/gtk/libgtk*.dll
|
||||
|
||||
@@ -1,194 +1,8 @@
|
||||
Overview of Changes in 4.6.1, 11-02-2022
|
||||
========================================
|
||||
|
||||
* GtkFontChooser:
|
||||
- Stop using PangoFc api
|
||||
- Fix a crash
|
||||
- Use new HarfBuzz api
|
||||
|
||||
* GtkMenuButton:
|
||||
- Update accessible description
|
||||
|
||||
* GtkTextView:
|
||||
- Fix intra-widget dnd
|
||||
|
||||
* Printing:
|
||||
- Fix an fd leak
|
||||
|
||||
* Input:
|
||||
- Make sure input methods get focus-in events
|
||||
- Always flush events to avoid scroll event pileup
|
||||
- Support hold events
|
||||
- Update keysyms from libxkbcommon
|
||||
|
||||
* Theme:
|
||||
- Improve text selection legibility
|
||||
|
||||
* Introspection:
|
||||
- Add missing nullable annotations everywhere
|
||||
|
||||
* Build:
|
||||
- Make stack noexec again
|
||||
- Avoid symbol leaks
|
||||
- Drop unneeded script data
|
||||
|
||||
* Windows:
|
||||
- Stop using WM_SYNCPAINT
|
||||
- Relax check for GL 3.x legacy contexts
|
||||
- Use native apis for language names
|
||||
- Rewrite the keymap code
|
||||
- Use the GL renderer by default
|
||||
|
||||
* Wayland:
|
||||
- Fix support for the new high-contrast setting
|
||||
- Avoid redundant scale changes
|
||||
- Fix DND hotspot handling
|
||||
- Don't always restore the saved size when floating
|
||||
|
||||
* MacOS:
|
||||
- Various performance improvements
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Galician
|
||||
Hebrew
|
||||
Japanese
|
||||
Lithuanian
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Russian
|
||||
Slovenian
|
||||
Spanish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.0, 30-12-2021
|
||||
========================================
|
||||
|
||||
* GtkProgressBar:
|
||||
- Fix handling of "inverted"
|
||||
|
||||
* GtkLabel:
|
||||
- Add a "natural wrap mode" property to influence how
|
||||
natural width is determined
|
||||
|
||||
* GtkTextView
|
||||
- Scroll insertion on-screen after undo / redo
|
||||
|
||||
* gsk:
|
||||
- Abort region diffing when changes are too complex
|
||||
|
||||
* gdk:
|
||||
- Avoid compressing discrete scroll events
|
||||
- Fix problems with hiding windows
|
||||
- Improve GL and GLES version checks
|
||||
|
||||
* Wayland:
|
||||
- Support new high-contrast setting
|
||||
|
||||
* Inspector:
|
||||
- Add DND inspection support
|
||||
|
||||
* build:
|
||||
- Avoid deprecated meson apis
|
||||
|
||||
* Translation updates
|
||||
Galician
|
||||
Portuguese
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.5.1, 16-12-2021
|
||||
========================================
|
||||
|
||||
* GtkWidget sizing has been rewritten to implement
|
||||
width-for-height more properly. This had some fallout,
|
||||
and some widgets may still not react kindly to the
|
||||
new way of doing things.
|
||||
|
||||
See https://blog.gtk.org/2021/12/03/sizable-news/
|
||||
for details, and please file issues if you notice fallout.
|
||||
Overview of Changes
|
||||
===================
|
||||
|
||||
* Rename git `master` branch to `main`
|
||||
|
||||
* Css:
|
||||
- Fully support font-variant-caps
|
||||
- Fix a crash with gradients
|
||||
|
||||
* Make various widgets activatable:
|
||||
- GtkComboBox
|
||||
- GtkDropDown
|
||||
|
||||
* GtkPopover:
|
||||
- Make focus indicators not disappear
|
||||
|
||||
* GtkTextView:
|
||||
- Don't leave embedded children stranded when scrolling
|
||||
- Don't insert Emoji into non-editable textviews
|
||||
- Fix Emoji chooser positioning
|
||||
- Fix problems with pasting text
|
||||
- Improve scroll-to-mark behavior
|
||||
- Support right-aligned, centered and decimal tabs
|
||||
- Make child anchor replacement character settable
|
||||
- Provide more context to input methods
|
||||
|
||||
* GtkDragIcon:
|
||||
- Provide default icons for paintables and files
|
||||
|
||||
* GtkBuilder:
|
||||
- Speed up template precompilation
|
||||
|
||||
* Actions:
|
||||
- Reduce allocations during signal emissions
|
||||
- Avoid duplication and unnecessary recursion
|
||||
|
||||
* Inspector:
|
||||
- Show the selected im-module in the General tab
|
||||
- Add a clipboard viewer
|
||||
- Make the recorder record events too
|
||||
- Add a graph visualizing gtk_widget_measure()
|
||||
|
||||
* Gsk:
|
||||
- Fix hexbox rendering
|
||||
- Fix transformed linear gradient rendering
|
||||
|
||||
* Printing:
|
||||
- Fix dialog-less printing
|
||||
|
||||
* Windows:
|
||||
- Use the common EGL setup code
|
||||
- Respect GDK_DEBUG=gl-egl
|
||||
- Fix AeroSnap indicator and positioning
|
||||
|
||||
* X11:
|
||||
- Improve behavior of windows drags on headerbar controls
|
||||
- Trap errors for RANDR changes
|
||||
- Fix problems with drag icons
|
||||
|
||||
* Wayland:
|
||||
- Ensure we prefer the Wayland im-module over others
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Catalan
|
||||
Croatian
|
||||
Friulian
|
||||
Galician
|
||||
Hebrew
|
||||
Icelandic
|
||||
Italian
|
||||
Latvian
|
||||
Lithuanian
|
||||
Occitan
|
||||
Persian
|
||||
Portuguese
|
||||
Spanish
|
||||
Swedish
|
||||
Ukrainian
|
||||
|
||||
Overview of Changes in 4.5.0
|
||||
============================
|
||||
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
|
||||
"branch" : "main"
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
|
||||
"branch" : "main"
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
|
||||
"branch" : "main"
|
||||
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ if 'DESTDIR' not in os.environ:
|
||||
|
||||
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
|
||||
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
|
||||
gtk_mediamodule_dir = os.path.join(gtk_moduledir, 'media')
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||
@@ -40,6 +40,6 @@ if 'DESTDIR' not in os.environ:
|
||||
gio_querymodules = 'gio-querymodules'
|
||||
subprocess.call([gio_querymodules, gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for media backends...')
|
||||
os.makedirs(gtk_mediamodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_mediamodule_dir])
|
||||
print('Updating module cache for input methods...')
|
||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_immodule_dir])
|
||||
|
||||
@@ -17,7 +17,7 @@ executable('gtk4-constraint-editor',
|
||||
c_args: common_cflags,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false,
|
||||
)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <pango/pangofc-font.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
@@ -18,81 +18,15 @@
|
||||
|
||||
#include "language-names.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
#ifndef ISO_CODES_PREFIX
|
||||
#define ISO_CODES_PREFIX "/usr"
|
||||
#endif
|
||||
|
||||
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
|
||||
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
|
||||
#endif
|
||||
|
||||
static GHashTable *language_map;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* if we are using native Windows use native Windows API for language names */
|
||||
static BOOL CALLBACK
|
||||
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
|
||||
{
|
||||
wchar_t *langname_w = NULL;
|
||||
wchar_t locale_abbrev_w[9];
|
||||
gchar *langname, *locale_abbrev, *locale, *p;
|
||||
gint i;
|
||||
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
|
||||
GHashTable *ht_scripts_langs = (GHashTable *) param;
|
||||
PangoLanguage *lang;
|
||||
|
||||
gint langname_size, locale_abbrev_size;
|
||||
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
langname_w = g_new0 (wchar_t, langname_size);
|
||||
|
||||
if (langname_size == 0)
|
||||
return FALSE;
|
||||
|
||||
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
|
||||
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
|
||||
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
|
||||
p = strchr (locale, '-');
|
||||
lang = pango_language_from_string (locale);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
/*
|
||||
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
|
||||
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
|
||||
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
|
||||
*/
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
|
||||
if (locale_abbrev_size > 0)
|
||||
{
|
||||
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
|
||||
|
||||
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
|
||||
lang = pango_language_from_string (locale_abbrev);
|
||||
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
|
||||
g_hash_table_insert (ht_scripts_langs, lang, langname);
|
||||
|
||||
g_free (locale_abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (locale);
|
||||
g_free (langname_w);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else /* non-Windows */
|
||||
|
||||
static char *
|
||||
get_first_item_in_semicolon_list (const char *list)
|
||||
{
|
||||
@@ -276,7 +210,6 @@ languages_variant_init (const char *variant)
|
||||
g_free (filename);
|
||||
g_free (buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
languages_init (void)
|
||||
@@ -285,13 +218,8 @@ languages_init (void)
|
||||
return;
|
||||
|
||||
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
|
||||
#else
|
||||
languages_variant_init ("iso_639");
|
||||
languages_variant_init ("iso_639_3");
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save _As...</attribute>
|
||||
<attribute name="action">app.save-as</attribute>
|
||||
<attribute name="accel"><Control><Shift>s</attribute>
|
||||
<attribute name="accel"><Control>s</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
|
||||
@@ -98,7 +98,6 @@ demos = files([
|
||||
'transparent.c',
|
||||
'tree_store.c',
|
||||
'video_player.c',
|
||||
'font_features.c',
|
||||
])
|
||||
|
||||
gtkdemo_deps = [ libgtk_dep, ]
|
||||
@@ -129,9 +128,14 @@ extra_demo_sources = files([
|
||||
'script-names.c',
|
||||
'unicode-names.c',
|
||||
'suggestionentry.c',
|
||||
'language-names.c',
|
||||
])
|
||||
|
||||
if harfbuzz_dep.found() and pangoft_dep.found()
|
||||
demos += files(['font_features.c'])
|
||||
extra_demo_sources += files(['language-names.c'])
|
||||
gtkdemo_deps += [ harfbuzz_dep, epoxy_dep ]
|
||||
endif
|
||||
|
||||
if os_unix
|
||||
demos += files('pagesetup.c')
|
||||
endif
|
||||
@@ -170,7 +174,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile : 'gtkdemo.gresource.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -184,7 +187,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile : 'gtkdemo_resources.c.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate-source',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -198,7 +200,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : gtkdemo_gresource,
|
||||
output : 'gtkdemo_resources.o',
|
||||
command : [ld,
|
||||
'-z', 'noexecstack',
|
||||
'-r',
|
||||
'-b','binary',
|
||||
'@INPUT@',
|
||||
@@ -209,7 +210,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : gtkdemo_resources_binary,
|
||||
output : 'gtkdemo_resources2.o',
|
||||
command : [objcopy,
|
||||
'--strip-all',
|
||||
'--add-symbol','_g_binary_gtkdemo_resource_data=.data:0',
|
||||
'@INPUT@',
|
||||
'@OUTPUT@'])
|
||||
@@ -242,7 +242,7 @@ executable('gtk4-demo',
|
||||
c_args: gtkdemo_args + demo_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
@@ -252,7 +252,7 @@ executable('gtk4-demo-application',
|
||||
c_args: gtkdemo_args + common_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ executable('gtk4-icon-browser',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ demo_profile = get_option('profile')
|
||||
|
||||
demo_conf_h = declare_dependency(
|
||||
sources: custom_target('demo-header',
|
||||
command: [gen_demo_header, meson.project_source_root(), demo_profile],
|
||||
command: [gen_demo_header, meson.source_root(), demo_profile],
|
||||
capture: true,
|
||||
output: 'demo_conf.h',
|
||||
build_by_default: true,
|
||||
|
||||
@@ -17,7 +17,7 @@ executable('gtk4-node-editor',
|
||||
c_args: [
|
||||
'-DNODE_EDITOR_SOURCE_DIR="@0@/../../testsuite/gsk/compare/"'.format(meson.current_source_dir())
|
||||
] + common_cflags,
|
||||
win_subsystem: 'windows',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false,
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ executable('gtk4-print-editor',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -18,7 +18,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile: 'widgetfactory.gresource.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -32,7 +31,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
depfile: 'widgetfactory_resources.c.d',
|
||||
command : [glib_compile_resources,
|
||||
'--generate-source',
|
||||
'--internal',
|
||||
'--target=@OUTPUT@',
|
||||
'--dependency-file=@DEPFILE@',
|
||||
'--sourcedir=' + meson.current_source_dir(),
|
||||
@@ -46,7 +44,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : widgetfactory_gresource,
|
||||
output : 'widgetfactory_resources.o',
|
||||
command : [ld,
|
||||
'-z', 'noexecstack',
|
||||
'-r',
|
||||
'-b','binary',
|
||||
'@INPUT@',
|
||||
@@ -57,7 +54,6 @@ if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_ad
|
||||
input : widgetfactory_resources_binary,
|
||||
output : 'widgetfactory_resources2.o',
|
||||
command : [objcopy,
|
||||
'--strip-all',
|
||||
'--add-symbol','_g_binary_widgetfactory_resource_data=.data:0',
|
||||
'@INPUT@',
|
||||
'@OUTPUT@'])
|
||||
@@ -78,7 +74,7 @@ executable('gtk4-widget-factory',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -1927,12 +1927,6 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="tooltip-text" translatable="1">Insert something</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton">
|
||||
<property name="rgba">#9141AC</property>
|
||||
<property name="tooltip-text" translatable="1">Select a color</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -20,7 +20,7 @@ name = "basic"
|
||||
show_index_summary = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
|
||||
@@ -20,7 +20,7 @@ name = "basic"
|
||||
show_index_summary = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
|
||||
@@ -43,7 +43,7 @@ show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
|
||||
[extra]
|
||||
content_files = [
|
||||
|
||||
@@ -38,7 +38,7 @@ show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
|
||||
@@ -170,7 +170,7 @@ activate (GtkApplication *app,
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
|
||||
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
button = gtk_button_new_with_label ("Hello World");
|
||||
@@ -752,7 +752,7 @@ templates, resources, application menus, settings, [class@Gtk.HeaderBar], [class
|
||||
|
||||
The full, buildable sources for these examples can be found in the
|
||||
`examples` directory of the GTK source distribution, or
|
||||
[online](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples) in the GTK
|
||||
[online](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples) in the GTK
|
||||
source code repository. You can build each example separately by using make
|
||||
with the `Makefile.example` file. For more information, see the `README`
|
||||
included in the examples directory.
|
||||
@@ -972,7 +972,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application2/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application2/exampleappwin.c))
|
||||
|
||||
You may have noticed that we used the `_from_resource()` variant of the function
|
||||
that sets a template. Now we need to use
|
||||
@@ -1043,7 +1043,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application3/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c))
|
||||
|
||||
Now we revisit the `example_app_window_open()` function that is called for each
|
||||
commandline argument, and construct a GtkTextView that we then add as a page
|
||||
@@ -1087,7 +1087,7 @@ example_app_window_open (ExampleAppWindow *win,
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application3/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c))
|
||||
|
||||
Lastly, we add a [class@Gtk.StackSwitcher] to the titlebar area in the UI file, and we
|
||||
tell it to display information about our stack.
|
||||
@@ -1188,7 +1188,7 @@ example_app_class_init (ExampleAppClass *class)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application4/exampleapp.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application4/exampleapp.c))
|
||||
|
||||
Our preferences menu item does not do anything yet, but the Quit menu item
|
||||
is fully functional. Note that it can also be activated by the usual Ctrl-Q
|
||||
@@ -1258,7 +1258,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application5/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application5/exampleappwin.c))
|
||||
|
||||
The code to connect the font setting is a little more involved, since there
|
||||
is no simple object property that it corresponds to, so we are not going to
|
||||
@@ -1429,7 +1429,7 @@ preferences_activated (GSimpleAction *action,
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application6/exampleapp.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application6/exampleapp.c))
|
||||
|
||||
After all this work, our application can now show a preference dialog
|
||||
like this:
|
||||
@@ -1549,7 +1549,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application7/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application7/exampleappwin.c))
|
||||
|
||||
With the search bar, our application now looks like this:
|
||||
|
||||
@@ -1682,7 +1682,7 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application8/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application8/exampleappwin.c))
|
||||
|
||||
What our application looks like now:
|
||||
|
||||
@@ -1760,10 +1760,10 @@ example_app_window_init (ExampleAppWindow *win)
|
||||
...
|
||||
```
|
||||
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application9/exampleappwin.c))
|
||||
([full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c))
|
||||
|
||||
We also need a function that counts the lines of the currently active tab,
|
||||
and updates the `lines` label. See the [full source](https://gitlab.gnome.org/GNOME/gtk/blob/main/examples/application9/exampleappwin.c)
|
||||
and updates the `lines` label. See the [full source](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c)
|
||||
if you are interested in the details.
|
||||
|
||||
This brings our example application to this appearance:
|
||||
|
||||
@@ -16,6 +16,7 @@ SYNOPSIS
|
||||
| **gtk4-builder-tool** enumerate <FILE>
|
||||
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** precompile [OPTIONS...] <FILE>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -83,3 +84,10 @@ to do manual fixups after the initial conversion.
|
||||
``--3to4``
|
||||
|
||||
Transform a GTK 3 UI definition file to the equivalent GTK 4 definitions.
|
||||
|
||||
Precompilation
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
The ``precompile`` command creates a more compact, and faster to load compiled
|
||||
form of the ui file that is understood by GtkBuilder. The output is written
|
||||
to a file with the extension ``.precompiled``.
|
||||
|
||||
@@ -43,7 +43,7 @@ show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/master/"
|
||||
|
||||
[extra]
|
||||
# The same order will be used when generating the index
|
||||
|
||||
@@ -42,7 +42,7 @@ univocally identifies events that are related to the same
|
||||
interaction.
|
||||
|
||||
When GTK creates a `GdkSurface`, it connects to the ::event
|
||||
signal on it, which receives all of these input events. Surfaces
|
||||
signal on it, which receives all of these input events. Surfaces have
|
||||
have signals and properties, e.g. to deal with window management
|
||||
related events.
|
||||
|
||||
|
||||
@@ -1276,15 +1276,6 @@ is provided in the form of a `GtkIconPaintable` (this can be checked with
|
||||
[method@Gtk.IconPaintable.is_symbolic]), you have to call
|
||||
[method@Gtk.IconPaintable.get_icon_name] and set the icon name on a `GtkImage`.
|
||||
|
||||
### Adapt to GtkImage changes
|
||||
`GtkPicture`'s behaviour was "split out" of `GtkImage` as the latter was covering
|
||||
too many use cases; if you're loading an icon, [class@Gtk.Image] in GTK3 and GTK4 are
|
||||
perfectly equivalent. If you are loading a more complex image asset, like a picture
|
||||
or a thumbnail, then [class@Gtk.Picture] is the appropriate widget.
|
||||
|
||||
One noteworthy distinction is that while `GtkImage` has its size computed by
|
||||
GTK, `GtkPicture` lets you decide about the size.
|
||||
|
||||
### Update to GtkFileChooser API changes
|
||||
|
||||
`GtkFileChooser` moved to a GFile-based API. If you need to convert a path
|
||||
@@ -1382,5 +1373,5 @@ a new family of widgets for this purpose that uses list models instead
|
||||
of tree models, and widgets instead of cell renderers.
|
||||
|
||||
To learn more about the new list widgets, you can read the [List Widget
|
||||
Overview](https://docs.gtk.org/gtk4/section-list-widget.html).
|
||||
Overview](#ListWidget).
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ GTK with your code applied, and run the test suite, on multiple platforms
|
||||
and architectures, and verify that nothing breaks. They also allow us to
|
||||
do proper code reviews, so we can iterate over the changes.
|
||||
|
||||
You should follow the [contribution guide](https://gitlab.gnome.org/GNOME/gtk/blob/main/CONTRIBUTING.md)
|
||||
You should follow the [contribution guide](https://gitlab.gnome.org/GNOME/gtk/blob/master/CONTRIBUTING.md)
|
||||
for GTK, available on GitLab.
|
||||
|
||||
If you want to discuss your approach before or after working on it,
|
||||
|
||||
@@ -286,7 +286,7 @@ requires that GTK is compiled with support for that backend.
|
||||
The following backends can be selected, provided they are
|
||||
included in the GDK libraries you are using:
|
||||
|
||||
`macos`
|
||||
`quartz`
|
||||
: Selects the native Quartz backend
|
||||
|
||||
`win32`
|
||||
@@ -336,6 +336,9 @@ using and the GDK backend supports them:
|
||||
`gl`
|
||||
: Selects the "gl" OpenGL renderer
|
||||
|
||||
`ngl`
|
||||
: Selects the "ngl" OpenGL renderer
|
||||
|
||||
`vulkan`
|
||||
: Selects the Vulkan renderer
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
* `GdkAppLaunchContext` handles launching an application in a graphical context.
|
||||
*
|
||||
* It is an implementation of `GAppLaunchContext` that provides startup
|
||||
* notification and allows to launch applications on a specific workspace.
|
||||
* notification and allows to launch applications on a specific screen
|
||||
* or workspace.
|
||||
*
|
||||
* ## Launching an application
|
||||
*
|
||||
@@ -40,6 +41,7 @@
|
||||
*
|
||||
* context = gdk_display_get_app_launch_context (display);
|
||||
*
|
||||
* gdk_app_launch_context_set_display (display);
|
||||
* gdk_app_launch_context_set_timestamp (gdk_event_get_time (event));
|
||||
*
|
||||
* if (!g_app_info_launch_default_for_uri ("http://www.gtk.org", context, &error))
|
||||
@@ -194,10 +196,6 @@ gdk_app_launch_context_get_display (GdkAppLaunchContext *context)
|
||||
* This only works when running under a window manager that
|
||||
* supports multiple workspaces, as described in the
|
||||
* [Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec).
|
||||
* Specifically this sets the `_NET_WM_DESKTOP` property described
|
||||
* in that spec.
|
||||
*
|
||||
* This only works when using the X11 backend.
|
||||
*
|
||||
* When the workspace is not specified or @desktop is set to -1,
|
||||
* it is up to the window manager to pick one, typically it will
|
||||
|
||||
@@ -264,7 +264,7 @@ gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer)
|
||||
*
|
||||
* This is the `GCancellable` that was passed to [func@Gdk.content_deserialize_async].
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the cancellable for the current operation
|
||||
* Returns: (transfer none): the cancellable for the current operation
|
||||
*/
|
||||
GCancellable *
|
||||
gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer)
|
||||
|
||||
@@ -342,7 +342,7 @@ gdk_content_provider_write_mime_type_finish (GdkContentProvider *provider,
|
||||
/**
|
||||
* gdk_content_provider_get_value:
|
||||
* @provider: a `GdkContentProvider`
|
||||
* @value: (out caller-allocates): the `GValue` to fill
|
||||
* @value: the `GValue` to fill
|
||||
* @error: a `GError` location to store the error occurring
|
||||
*
|
||||
* Gets the contents of @provider stored in @value.
|
||||
|
||||
@@ -270,7 +270,7 @@ gdk_content_serializer_get_priority (GdkContentSerializer *serializer)
|
||||
*
|
||||
* This is the `GCancellable` that was passed to [func@content_serialize_async].
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the cancellable for the current operation
|
||||
* Returns: (transfer none): the cancellable for the current operation
|
||||
*/
|
||||
GCancellable *
|
||||
gdk_content_serializer_get_cancellable (GdkContentSerializer *serializer)
|
||||
|
||||
+2
-1
@@ -47,7 +47,8 @@
|
||||
* Cursors by themselves are not very interesting: they must be bound to a
|
||||
* window for users to see them. This is done with [method@Gdk.Surface.set_cursor]
|
||||
* or [method@Gdk.Surface.set_device_cursor]. Applications will typically
|
||||
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor] instead.
|
||||
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor]`
|
||||
* instead.
|
||||
*
|
||||
* Cursors are not bound to a given [class@Gdk.Display], so they can be shared.
|
||||
* However, the appearance of cursors may vary when used on different
|
||||
|
||||
+5
-1
@@ -132,6 +132,8 @@ gdk_device_class_init (GdkDeviceClass *klass)
|
||||
* GdkDevice:source: (attributes org.gtk.Property.get=gdk_device_get_source)
|
||||
*
|
||||
* Source type for the device.
|
||||
*
|
||||
* Deprecated: 4.6: Use GdkDeviceTool:tool-type instead
|
||||
*/
|
||||
device_props[PROP_SOURCE] =
|
||||
g_param_spec_enum ("source",
|
||||
@@ -596,6 +598,8 @@ gdk_device_get_has_cursor (GdkDevice *device)
|
||||
* Determines the type of the device.
|
||||
*
|
||||
* Returns: a `GdkInputSource`
|
||||
*
|
||||
* Deprecated: 4.6: Use gdk_device_tool_get_tool_type() instead
|
||||
*/
|
||||
GdkInputSource
|
||||
gdk_device_get_source (GdkDevice *device)
|
||||
@@ -1238,7 +1242,7 @@ gdk_device_get_num_touches (GdkDevice *device)
|
||||
*
|
||||
* Retrieves the current tool for @device.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the `GdkDeviceTool`
|
||||
* Returns: (transfer none): the `GdkDeviceTool`
|
||||
*/
|
||||
GdkDeviceTool *
|
||||
gdk_device_get_device_tool (GdkDevice *device)
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_device_get_display (GdkDevice *device);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSeat * gdk_device_get_seat (GdkDevice *device);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_6_FOR(gdk_device_tool_get_tool_type)
|
||||
GdkDeviceTool * gdk_device_get_device_tool (GdkDevice *device);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -1727,8 +1727,6 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||
self->have_egl_pixel_format_float =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
|
||||
self->have_egl_win32_libangle =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_ANGLE_d3d_share_handle_client_buffer");
|
||||
|
||||
if (self->have_egl_no_config_context)
|
||||
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
||||
|
||||
@@ -110,7 +110,6 @@ struct _GdkDisplay
|
||||
guint have_egl_swap_buffers_with_damage : 1;
|
||||
guint have_egl_no_config_context : 1;
|
||||
guint have_egl_pixel_format_float : 1;
|
||||
guint have_egl_win32_libangle : 1;
|
||||
};
|
||||
|
||||
struct _GdkDisplayClass
|
||||
|
||||
+81
-162
@@ -19,7 +19,7 @@
|
||||
* 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/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -522,9 +522,7 @@ _gdk_event_queue_find_first (GdkDisplay *display)
|
||||
if (pending_motion)
|
||||
return pending_motion;
|
||||
|
||||
if ((event->event_type == GDK_MOTION_NOTIFY ||
|
||||
(event->event_type == GDK_SCROLL && gdk_scroll_event_get_direction (event) == GDK_SCROLL_SMOOTH)) &&
|
||||
(event->flags & GDK_EVENT_FLUSHED) == 0)
|
||||
if (event->event_type == GDK_MOTION_NOTIFY && (event->flags & GDK_EVENT_FLUSHED) == 0)
|
||||
pending_motion = tmp_list;
|
||||
else
|
||||
return tmp_list;
|
||||
@@ -598,9 +596,6 @@ _gdk_event_unqueue (GdkDisplay *display)
|
||||
/*
|
||||
* If the last N events in the event queue are smooth scroll events
|
||||
* for the same surface and device, combine them into one.
|
||||
*
|
||||
* We give the remaining event a history with N items, and deltas
|
||||
* that are the sum over the history entries.
|
||||
*/
|
||||
void
|
||||
gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
@@ -610,6 +605,7 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
GdkDevice *device = NULL;
|
||||
GdkEvent *last_event = NULL;
|
||||
GList *scrolls = NULL;
|
||||
double delta_x, delta_y;
|
||||
GArray *history = NULL;
|
||||
GdkTimeCoord hist;
|
||||
|
||||
@@ -644,42 +640,35 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
l = l->prev;
|
||||
}
|
||||
|
||||
delta_x = delta_y = 0;
|
||||
|
||||
while (scrolls && scrolls->next != NULL)
|
||||
{
|
||||
GdkEvent *event = scrolls->data;
|
||||
GList *next = scrolls->next;
|
||||
double dx, dy;
|
||||
gboolean inherited = FALSE;
|
||||
|
||||
if (!history && ((GdkScrollEvent *)event)->history)
|
||||
{
|
||||
history = ((GdkScrollEvent *)event)->history;
|
||||
((GdkScrollEvent *)event)->history = NULL;
|
||||
inherited = TRUE;
|
||||
}
|
||||
|
||||
if (!history)
|
||||
history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
|
||||
if (!inherited)
|
||||
{
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
delta_x += dx;
|
||||
delta_y += dy;
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
|
||||
g_array_append_val (history, hist);
|
||||
}
|
||||
g_array_append_val (history, hist);
|
||||
|
||||
gdk_event_unref (event);
|
||||
g_queue_delete_link (&display->queued_events, scrolls);
|
||||
scrolls = next;
|
||||
}
|
||||
|
||||
if (scrolls && history)
|
||||
if (scrolls)
|
||||
{
|
||||
GdkEvent *old_event, *event;
|
||||
double dx, dy;
|
||||
@@ -687,29 +676,13 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
old_event = scrolls->data;
|
||||
|
||||
gdk_scroll_event_get_deltas (old_event, &dx, &dy);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (old_event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
g_array_append_val (history, hist);
|
||||
|
||||
dx = dy = 0;
|
||||
for (int i = 0; i < history->len; i++)
|
||||
{
|
||||
GdkTimeCoord *val = &g_array_index (history, GdkTimeCoord, i);
|
||||
dx += val->axes[GDK_AXIS_DELTA_X];
|
||||
dy += val->axes[GDK_AXIS_DELTA_Y];
|
||||
}
|
||||
|
||||
event = gdk_scroll_event_new (surface,
|
||||
device,
|
||||
gdk_event_get_device_tool (old_event),
|
||||
gdk_event_get_time (old_event),
|
||||
gdk_event_get_modifier_state (old_event),
|
||||
dx,
|
||||
dy,
|
||||
delta_x + dx,
|
||||
delta_y + dy,
|
||||
gdk_scroll_event_is_stop (old_event));
|
||||
|
||||
((GdkScrollEvent *)event)->history = history;
|
||||
@@ -719,6 +692,14 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
|
||||
gdk_event_unref (old_event);
|
||||
}
|
||||
|
||||
if (g_queue_get_length (&display->queued_events) == 1 &&
|
||||
g_queue_peek_head_link (&display->queued_events) == scrolls)
|
||||
{
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
|
||||
if (clock) /* might be NULL if surface was destroyed */
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -733,41 +714,24 @@ gdk_motion_event_push_history (GdkEvent *event,
|
||||
g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY));
|
||||
g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY));
|
||||
|
||||
if (G_UNLIKELY (!self->history))
|
||||
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
|
||||
if (((GdkMotionEvent *)history_event)->history)
|
||||
{
|
||||
GArray *history = ((GdkMotionEvent *)history_event)->history;
|
||||
g_array_append_vals (self->history, history->data, history->len);
|
||||
}
|
||||
if (!self->tool)
|
||||
return;
|
||||
|
||||
tool = gdk_event_get_device_tool (history_event);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (history_event);
|
||||
if (tool)
|
||||
{
|
||||
hist.flags = gdk_device_tool_get_axes (tool);
|
||||
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
|
||||
gdk_event_get_axis (history_event, i, &hist.axes[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
hist.flags = GDK_AXIS_FLAG_X | GDK_AXIS_FLAG_Y;
|
||||
gdk_event_get_position (history_event, &hist.axes[GDK_AXIS_X], &hist.axes[GDK_AXIS_Y]);
|
||||
}
|
||||
hist.flags = gdk_device_tool_get_axes (tool);
|
||||
|
||||
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
|
||||
gdk_event_get_axis (history_event, i, &hist.axes[i]);
|
||||
|
||||
if (G_UNLIKELY (!self->history))
|
||||
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
|
||||
g_array_append_val (self->history, hist);
|
||||
}
|
||||
|
||||
/* If the last N events in the event queue are motion notify
|
||||
* events for the same surface, drop all but the last.
|
||||
*
|
||||
* If a button is held down or the device has a tool, then
|
||||
* we give the remaining events a history containing the N-1
|
||||
* dropped events.
|
||||
*/
|
||||
void
|
||||
_gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
{
|
||||
@@ -777,6 +741,9 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
GdkDevice *pending_motion_device = NULL;
|
||||
GdkEvent *last_motion = NULL;
|
||||
|
||||
/* If the last N events in the event queue are motion notify
|
||||
* events for the same surface, drop all but the last */
|
||||
|
||||
tmp_list = g_queue_peek_tail_link (&display->queued_events);
|
||||
|
||||
while (tmp_list)
|
||||
@@ -813,17 +780,26 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
|
||||
if (last_motion != NULL)
|
||||
{
|
||||
if ((gdk_event_get_modifier_state (last_motion) &
|
||||
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) ||
|
||||
gdk_event_get_device_tool (last_motion) != NULL)
|
||||
gdk_motion_event_push_history (last_motion, pending_motions->data);
|
||||
GdkModifierType state = gdk_event_get_modifier_state (last_motion);
|
||||
|
||||
if (state &
|
||||
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK))
|
||||
gdk_motion_event_push_history (last_motion, pending_motions->data);
|
||||
}
|
||||
|
||||
gdk_event_unref (pending_motions->data);
|
||||
g_queue_delete_link (&display->queued_events, pending_motions);
|
||||
pending_motions = next;
|
||||
}
|
||||
|
||||
if (g_queue_get_length (&display->queued_events) == 1 &&
|
||||
g_queue_peek_head_link (&display->queued_events) == pending_motions)
|
||||
{
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (pending_motion_surface);
|
||||
if (clock) /* might be NULL if surface was destroyed */
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -927,9 +903,6 @@ gdk_event_get_pointer_emulated (GdkEvent *event)
|
||||
* Extract the axis value for a particular axis use from
|
||||
* an event structure.
|
||||
*
|
||||
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
|
||||
* on the device tool returned by [method@Gdk.Event.get_device_tool].
|
||||
*
|
||||
* Returns: %TRUE if the specified axis was found, otherwise %FALSE
|
||||
*/
|
||||
gboolean
|
||||
@@ -1156,9 +1129,6 @@ G_DEFINE_BOXED_TYPE (GdkEventSequence, gdk_event_sequence,
|
||||
*
|
||||
* Extracts all axis values from an event.
|
||||
*
|
||||
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
|
||||
* on the device tool returned by [method@Gdk.Event.get_device_tool].
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE
|
||||
*/
|
||||
gboolean
|
||||
@@ -1209,7 +1179,7 @@ gdk_event_get_event_type (GdkEvent *event)
|
||||
*
|
||||
* Extracts the surface associated with an event.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): The `GdkSurface` associated with the event
|
||||
* Returns: (transfer none): The `GdkSurface` associated with the event
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_event_get_surface (GdkEvent *event)
|
||||
@@ -2461,14 +2431,6 @@ gdk_touchpad_event_get_state (GdkEvent *event)
|
||||
return self->state;
|
||||
}
|
||||
|
||||
static GdkEventSequence *
|
||||
gdk_touchpad_event_get_sequence (GdkEvent *event)
|
||||
{
|
||||
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
|
||||
|
||||
return self->sequence;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_touchpad_event_get_position (GdkEvent *event,
|
||||
double *x,
|
||||
@@ -2488,7 +2450,7 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
|
||||
NULL,
|
||||
gdk_touchpad_event_get_state,
|
||||
gdk_touchpad_event_get_position,
|
||||
gdk_touchpad_event_get_sequence,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
@@ -2496,32 +2458,22 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
|
||||
GDK_DEFINE_EVENT_TYPE (GdkTouchpadEvent, gdk_touchpad_event,
|
||||
&gdk_touchpad_event_info,
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_SWIPE)
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH)
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_HOLD))
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH))
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy)
|
||||
gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy)
|
||||
{
|
||||
GdkTouchpadEvent *self;
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
|
||||
|
||||
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
|
||||
|
||||
self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
|
||||
|
||||
self->sequence = sequence;
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
@@ -2534,30 +2486,21 @@ gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy,
|
||||
double scale,
|
||||
double angle_delta)
|
||||
gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy,
|
||||
double scale,
|
||||
double angle_delta)
|
||||
{
|
||||
GdkTouchpadEvent *self;
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
|
||||
|
||||
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
|
||||
|
||||
self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
|
||||
|
||||
self->sequence = sequence;
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
@@ -2571,27 +2514,6 @@ gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_hold (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers)
|
||||
{
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_HOLD, surface, device, time);
|
||||
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
self->y = y;
|
||||
self->n_fingers = n_fingers;
|
||||
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_touchpad_event_get_gesture_phase:
|
||||
* @event: (type GdkTouchpadEvent): a touchpad event
|
||||
@@ -2607,8 +2529,7 @@ gdk_touchpad_event_get_gesture_phase (GdkEvent *event)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
|
||||
|
||||
return self->phase;
|
||||
}
|
||||
@@ -2628,8 +2549,7 @@ gdk_touchpad_event_get_n_fingers (GdkEvent *event)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE) ||
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_HOLD), 0);
|
||||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
|
||||
|
||||
return self->n_fingers;
|
||||
}
|
||||
@@ -2987,8 +2907,7 @@ gdk_motion_event_new (GdkSurface *surface,
|
||||
* to the application because they occurred in the same frame as @event.
|
||||
*
|
||||
* Note that only motion and scroll events record history, and motion
|
||||
* events do it only if one of the mouse buttons is down, or the device
|
||||
* has a tool.
|
||||
* events do it only if one of the mouse buttons is down.
|
||||
*
|
||||
* Returns: (transfer container) (array length=out_n_coords) (nullable): an
|
||||
* array of time and coordinates
|
||||
|
||||
@@ -169,8 +169,6 @@ typedef struct _GdkTouchpadEvent GdkTouchpadEvent;
|
||||
* @GDK_PAD_RING: A tablet pad axis event from a "ring".
|
||||
* @GDK_PAD_STRIP: A tablet pad axis event from a "strip".
|
||||
* @GDK_PAD_GROUP_MODE: A tablet pad group mode change.
|
||||
* @GDK_TOUCHPAD_HOLD: A touchpad hold gesture event, the current state
|
||||
* is determined by its phase field. Since: 4.6
|
||||
* @GDK_EVENT_LAST: marks the end of the GdkEventType enumeration.
|
||||
*
|
||||
* Specifies the type of the event.
|
||||
@@ -205,7 +203,6 @@ typedef enum
|
||||
GDK_PAD_RING,
|
||||
GDK_PAD_STRIP,
|
||||
GDK_PAD_GROUP_MODE,
|
||||
GDK_TOUCHPAD_HOLD,
|
||||
GDK_EVENT_LAST /* helper variable for decls */
|
||||
} GdkEventType;
|
||||
|
||||
|
||||
+11
-23
@@ -209,7 +209,7 @@ struct _GdkTouchEvent
|
||||
* @pointer_emulated: whether the scroll event was the result of
|
||||
* a pointer emulation
|
||||
* @tool: a `GdkDeviceTool`
|
||||
* @history: (element-type GdkTimeCoord): array of times and deltas
|
||||
* @history: (element-type GdkScrollHistory): array of times and deltas
|
||||
* for other scroll events that were compressed before delivering the
|
||||
* current event
|
||||
*
|
||||
@@ -233,7 +233,7 @@ struct _GdkScrollEvent
|
||||
gboolean pointer_emulated;
|
||||
gboolean is_stop;
|
||||
GdkDeviceTool *tool;
|
||||
GArray *history; /* <GdkTimeCoord> */
|
||||
GArray *history; /* <GdkScrollHistory> */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -402,7 +402,6 @@ struct _GdkTouchpadEvent
|
||||
{
|
||||
GdkEvent parent_instance;
|
||||
|
||||
GdkEventSequence *sequence;
|
||||
GdkModifierType state;
|
||||
gint8 phase;
|
||||
gint8 n_fingers;
|
||||
@@ -507,20 +506,18 @@ GdkEvent * gdk_touch_event_new (GdkEventType type,
|
||||
double *axes,
|
||||
gboolean emulating);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy);
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
@@ -533,15 +530,6 @@ GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
double scale,
|
||||
double angle_delta);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_hold (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers);
|
||||
|
||||
GdkEvent * gdk_pad_event_new_ring (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
|
||||
+18
-86
@@ -151,12 +151,6 @@ unmask_context (MaskedContext *mask)
|
||||
return GDK_GL_CONTEXT (GSIZE_TO_POINTER (GPOINTER_TO_SIZE (mask) & ~(gsize) 1));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
mask_is_surfaceless (MaskedContext *mask)
|
||||
{
|
||||
return GPOINTER_TO_SIZE (mask) & (gsize) 1;
|
||||
}
|
||||
|
||||
static void
|
||||
unref_unmasked (gpointer data)
|
||||
{
|
||||
@@ -185,7 +179,8 @@ gdk_gl_context_dispose (GObject *gobject)
|
||||
|
||||
if (priv->egl_context != NULL)
|
||||
{
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
EGLDisplay *egl_display = gdk_display_get_egl_display (display);
|
||||
|
||||
if (eglGetCurrentContext () == priv->egl_context)
|
||||
@@ -278,15 +273,7 @@ gdk_gl_context_real_realize (GdkGLContext *context,
|
||||
int i = 0;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (share != NULL)
|
||||
{
|
||||
gdk_gl_context_get_required_version (share, &major, &minor);
|
||||
gdk_gl_context_set_allowed_apis (context,
|
||||
gdk_gl_context_get_allowed_apis (share));
|
||||
}
|
||||
else
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||
forward_bit = gdk_gl_context_get_forward_compatible (context);
|
||||
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ||
|
||||
@@ -587,8 +574,8 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
glViewport (0, 0, ww, wh);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (priv->egl_context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
|
||||
glDrawBuffers (1, (GLenum[1]) { gdk_gl_context_get_use_es (context) ? GL_BACK : GL_BACK_LEFT });
|
||||
if (priv->egl_context)
|
||||
glDrawBuffers (1, (GLenum[1]) { GL_BACK_LEFT });
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1010,33 +997,16 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_check_version (GdkGLContext *self,
|
||||
int required_gl_major,
|
||||
int required_gl_minor,
|
||||
int required_gles_major,
|
||||
int required_gles_minor)
|
||||
gdk_gl_context_check_version (GdkGLContext *context,
|
||||
int required_major,
|
||||
int required_minor)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (required_gl_minor < 10, FALSE);
|
||||
g_return_val_if_fail (required_gles_minor < 10, FALSE);
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (required_minor < 10, FALSE);
|
||||
|
||||
if (!gdk_gl_context_is_realized (self))
|
||||
return FALSE;
|
||||
|
||||
switch (priv->api)
|
||||
{
|
||||
case GDK_GL_API_GL:
|
||||
return priv->gl_version >= required_gl_major * 10 + required_gl_minor;
|
||||
|
||||
case GDK_GL_API_GLES:
|
||||
return priv->gl_version >= required_gles_major * 10 + required_gles_minor;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
}
|
||||
return priv->gl_version >= required_major * 10 + required_minor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1056,29 +1026,26 @@ gdk_gl_context_get_required_version (GdkGLContext *context,
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
gboolean force_gles = FALSE;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GdkDisplay *display;
|
||||
#endif
|
||||
int default_major, default_minor;
|
||||
int maj, min;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
force_gles = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES);
|
||||
#endif
|
||||
|
||||
/* libANGLE on Windows at least requires GLES 3.0+ */
|
||||
if (display->have_egl_win32_libangle)
|
||||
force_gles = TRUE;
|
||||
|
||||
/* Default fallback values for uninitialised contexts; we
|
||||
* enforce a context version number of 3.2 for desktop GL,
|
||||
* and 2.0 for GLES
|
||||
*/
|
||||
if (gdk_gl_context_get_use_es (context) || force_gles)
|
||||
{
|
||||
default_major = display->have_egl_win32_libangle ? 3 : 2;
|
||||
default_major = 2;
|
||||
default_minor = 0;
|
||||
}
|
||||
else
|
||||
@@ -1356,7 +1323,6 @@ gl_debug_message_callback (GLenum source,
|
||||
const char *message_source;
|
||||
const char *message_type;
|
||||
const char *message_severity;
|
||||
GLogLevelFlags log_level;
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
|
||||
return;
|
||||
@@ -1418,31 +1384,22 @@ gl_debug_message_callback (GLenum source,
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH:
|
||||
message_severity = "High";
|
||||
log_level = G_LOG_LEVEL_CRITICAL;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||
message_severity = "Medium";
|
||||
log_level = G_LOG_LEVEL_WARNING;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_LOW:
|
||||
message_severity = "Low";
|
||||
log_level = G_LOG_LEVEL_MESSAGE;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||
message_severity = "Notification";
|
||||
log_level = G_LOG_LEVEL_INFO;
|
||||
break;
|
||||
default:
|
||||
message_severity = "Unknown";
|
||||
log_level = G_LOG_LEVEL_MESSAGE;
|
||||
}
|
||||
|
||||
/* There's no higher level function taking a log level argument... */
|
||||
g_log_structured_standard (G_LOG_DOMAIN, log_level,
|
||||
__FILE__, G_STRINGIFY (__LINE__),
|
||||
G_STRFUNC,
|
||||
"OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
|
||||
message_source, message_type, message_severity, message);
|
||||
g_warning ("OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
|
||||
message_source, message_type, message_severity, message);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1698,31 +1655,6 @@ gdk_gl_context_clear_current (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_gl_context_clear_current_if_surface:
|
||||
* @surface: surface to clear for
|
||||
*
|
||||
* Does a gdk_gl_context_clear_current() if the current context is attached
|
||||
* to @surface, leaves the current context alone otherwise.
|
||||
**/
|
||||
void
|
||||
gdk_gl_context_clear_current_if_surface (GdkSurface *surface)
|
||||
{
|
||||
MaskedContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current != NULL && !mask_is_surfaceless (current))
|
||||
{
|
||||
GdkGLContext *context = unmask_context (current);
|
||||
|
||||
if (gdk_gl_context_get_surface (context) != surface)
|
||||
return;
|
||||
|
||||
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_get_current:
|
||||
*
|
||||
|
||||
@@ -99,8 +99,6 @@ gboolean gdk_gl_backend_can_be_used (GdkGLBackend
|
||||
GError **error);
|
||||
void gdk_gl_backend_use (GdkGLBackend backend_type);
|
||||
|
||||
void gdk_gl_context_clear_current_if_surface (GdkSurface *surface);
|
||||
|
||||
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
|
||||
@@ -111,10 +109,8 @@ void gdk_gl_context_set_is_legacy (GdkGLContext
|
||||
gboolean is_legacy);
|
||||
|
||||
gboolean gdk_gl_context_check_version (GdkGLContext *context,
|
||||
int required_gl_major,
|
||||
int required_gl_minor,
|
||||
int required_gles_major,
|
||||
int required_gles_minor);
|
||||
int required_major,
|
||||
int required_minor);
|
||||
|
||||
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
|
||||
void gdk_gl_context_push_debug_group (GdkGLContext *context,
|
||||
|
||||
+7
-20
@@ -21,7 +21,6 @@
|
||||
#include "gdkgltextureprivate.h"
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
@@ -175,19 +174,10 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
glGenFramebuffers (1, &fbo);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
if (gdk_gl_context_check_version (self->context, 4, 3, 3, 1))
|
||||
{
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_read_format = GL_RGBA;
|
||||
gl_read_type = GL_UNSIGNED_BYTE;
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
}
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
|
||||
if (download->format == actual_format &&
|
||||
(download->stride == expected_stride))
|
||||
@@ -315,11 +305,9 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
GLint active_texture;
|
||||
GLint internal_format;
|
||||
|
||||
/* Abort if somebody else is GL-ing here... */
|
||||
if (self->context != gdk_gl_context_get_current () ||
|
||||
/* ... or glGetTexLevelParameter() isn't supported */
|
||||
!gdk_gl_context_check_version (self->context, 0, 0, 3, 1))
|
||||
if (self->context != gdk_gl_context_get_current ())
|
||||
{
|
||||
/* Somebody else is GL-ing here, abort! */
|
||||
texture->format = GDK_MEMORY_DEFAULT;
|
||||
return;
|
||||
}
|
||||
@@ -392,8 +380,7 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
* which will happen when the GdkTexture object is finalized, or due to
|
||||
* an explicit call of [method@Gdk.GLTexture.release].
|
||||
*
|
||||
* Return value: (transfer full) (type GdkGLTexture): A newly-created
|
||||
* `GdkTexture`
|
||||
* Return value: (transfer full): A newly-created `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_gl_texture_new (GdkGLContext *context,
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Updates https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms.h from upstream (X.org 7.x),
|
||||
# Updates https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms.h from upstream (X.org 7.x),
|
||||
# from https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
#
|
||||
#
|
||||
# Author : Simos Xenitellis <simos at gnome dot org>.
|
||||
# Author : Bastien Nocera <hadess@hadess.net>
|
||||
# Version : 1.2
|
||||
#
|
||||
# Input : https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
# Input : https://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h
|
||||
# Output : https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms.h
|
||||
#
|
||||
# Output : https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms.h
|
||||
#
|
||||
# Notes : It downloads keysymdef.h from the Internet, if not found locally,
|
||||
# Notes : and creates an updated gdkkeysyms.h
|
||||
# Notes : This version updates the source of gdkkeysyms.h from CVS to the GIT server.
|
||||
@@ -24,7 +24,7 @@ if ( ! -f "keysymdef.h" )
|
||||
{
|
||||
print "Trying to download keysymdef.h from\n";
|
||||
print "http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n";
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n"
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\n"
|
||||
unless system("wget -c -O keysymdef.h \"http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h\"") == 0;
|
||||
print " done.\n\n";
|
||||
}
|
||||
@@ -39,7 +39,7 @@ if ( ! -f "XF86keysym.h" )
|
||||
{
|
||||
print "Trying to download XF86keysym.h from\n";
|
||||
print "http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n";
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n"
|
||||
die "Unable to download keysymdef.h from http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\n"
|
||||
unless system("wget -c -O XF86keysym.h \"http://cgit.freedesktop.org/xorg/proto/x11proto/plain/XF86keysym.h\"") == 0;
|
||||
print " done.\n\n";
|
||||
}
|
||||
@@ -82,7 +82,7 @@ print OUT_GDKKEYSYMS $LICENSE_HEADER;
|
||||
print OUT_GDKKEYSYMS<<EOF;
|
||||
|
||||
/*
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms-update.pl
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms-update.pl
|
||||
* using the input file
|
||||
* http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
* and
|
||||
@@ -111,7 +111,7 @@ while (<IN_KEYSYMDEF>)
|
||||
|
||||
$_ = $keysymelements[1];
|
||||
die "Internal error, was expecting \"XC_*\", found: $_\n" if ( ! /^XK_/ );
|
||||
|
||||
|
||||
$_ = $keysymelements[2];
|
||||
die "Internal error, was expecting \"0x*\", found: $_\n" if ( ! /^0x/ );
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/main/gdk/gdkkeysyms-update.pl
|
||||
* File auto-generated from script https://gitlab.gnome.org/GNOME/gtk/tree/master/gdk/gdkkeysyms-update.pl
|
||||
* using the input file
|
||||
* http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
|
||||
* and
|
||||
|
||||
+43
-58
@@ -369,7 +369,7 @@ static const struct {
|
||||
{ 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
|
||||
{ 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
|
||||
{ 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
|
||||
{ 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */
|
||||
{ 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
|
||||
@@ -436,22 +436,22 @@ static const struct {
|
||||
{ 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
|
||||
{ 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
|
||||
{ 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
|
||||
{ 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */
|
||||
{ 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
|
||||
{ 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
/* 0x08a1 leftradical ? ??? */
|
||||
/* 0x08a2 topleftradical ? ??? */
|
||||
/* 0x08a3 horizconnector ? ??? */
|
||||
{ 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
|
||||
{ 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
|
||||
{ 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
|
||||
{ 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */
|
||||
{ 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */
|
||||
{ 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */
|
||||
{ 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */
|
||||
{ 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */
|
||||
{ 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */
|
||||
{ 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */
|
||||
{ 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */
|
||||
{ 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */
|
||||
{ 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */
|
||||
/* 0x08a7 topleftsqbracket ? ??? */
|
||||
/* 0x08a8 botleftsqbracket ? ??? */
|
||||
/* 0x08a9 toprightsqbracket ? ??? */
|
||||
/* 0x08aa botrightsqbracket ? ??? */
|
||||
/* 0x08ab topleftparens ? ??? */
|
||||
/* 0x08ac botleftparens ? ??? */
|
||||
/* 0x08ad toprightparens ? ??? */
|
||||
/* 0x08ae botrightparens ? ??? */
|
||||
/* 0x08af leftmiddlecurlybrace ? ??? */
|
||||
/* 0x08b0 rightmiddlecurlybrace ? ??? */
|
||||
/* 0x08b1 topleftsummation ? ??? */
|
||||
/* 0x08b2 botleftsummation ? ??? */
|
||||
/* 0x08b3 topvertsummationconnector ? ??? */
|
||||
@@ -467,8 +467,8 @@ static const struct {
|
||||
{ 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */
|
||||
{ 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
|
||||
{ 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
|
||||
{ 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */
|
||||
{ 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
|
||||
{ 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
|
||||
/* 0x08c9 similarequal ? ??? */
|
||||
{ 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
|
||||
{ 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
|
||||
{ 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
|
||||
@@ -485,7 +485,7 @@ static const struct {
|
||||
{ 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
|
||||
{ 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
|
||||
{ 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
|
||||
/* 0x09df blank ? ??? */
|
||||
{ 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */
|
||||
{ 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */
|
||||
{ 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
|
||||
{ 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
|
||||
@@ -499,11 +499,11 @@ static const struct {
|
||||
{ 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
|
||||
{ 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */
|
||||
{ 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
|
||||
{ 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
|
||||
{ 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
|
||||
/* 0x09ef horizlinescan1 ? ??? */
|
||||
/* 0x09f0 horizlinescan3 ? ??? */
|
||||
{ 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
{ 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
|
||||
{ 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
|
||||
/* 0x09f2 horizlinescan7 ? ??? */
|
||||
/* 0x09f3 horizlinescan9 ? ??? */
|
||||
{ 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
|
||||
{ 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
|
||||
{ 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
|
||||
@@ -519,9 +519,9 @@ static const struct {
|
||||
{ 0x0aa8, 0x200a }, /* hairspace HAIR SPACE */
|
||||
{ 0x0aa9, 0x2014 }, /* emdash — EM DASH */
|
||||
{ 0x0aaa, 0x2013 }, /* endash – EN DASH */
|
||||
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
|
||||
/* 0x0aac signifblank ? ??? */
|
||||
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
|
||||
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
|
||||
/* 0x0aaf doubbaselinedot ? ??? */
|
||||
{ 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */
|
||||
{ 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */
|
||||
{ 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */
|
||||
@@ -532,9 +532,9 @@ static const struct {
|
||||
{ 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
|
||||
{ 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */
|
||||
{ 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
|
||||
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
|
||||
{ 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
|
||||
{ 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
|
||||
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
|
||||
{ 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
|
||||
/* 0x0abf marker ? ??? */
|
||||
{ 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
|
||||
{ 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
|
||||
@@ -546,13 +546,12 @@ static const struct {
|
||||
{ 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */
|
||||
{ 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */
|
||||
{ 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */
|
||||
{ 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */
|
||||
{ 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */
|
||||
{ 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
|
||||
{ 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
|
||||
{ 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
|
||||
{ 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */
|
||||
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
|
||||
{ 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
|
||||
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
|
||||
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
|
||||
@@ -561,7 +560,7 @@ static const struct {
|
||||
{ 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */
|
||||
{ 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
|
||||
{ 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */
|
||||
{ 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */
|
||||
{ 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */
|
||||
{ 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */
|
||||
{ 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
|
||||
{ 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
|
||||
@@ -806,16 +805,15 @@ static const struct {
|
||||
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
|
||||
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
|
||||
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
|
||||
{ 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */
|
||||
/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
|
||||
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
|
||||
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
|
||||
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
|
||||
{ 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
|
||||
{ 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
|
||||
{ 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
|
||||
/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */
|
||||
{ 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
|
||||
{ 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */
|
||||
{ 0x13a4, 0x20ac }, /* Euro € EURO SIGN */
|
||||
{ 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */
|
||||
{ 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */
|
||||
{ 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
|
||||
@@ -837,13 +835,18 @@ static const struct {
|
||||
/* Following items added to GTK, not in the xterm table */
|
||||
|
||||
/* A few ASCII control characters */
|
||||
|
||||
#ifndef GDK_WINDOWING_WIN32
|
||||
{ 0xFF08 /* Backspace */, '\b' },
|
||||
{ 0xFF09 /* Tab */, '\t' },
|
||||
#endif
|
||||
|
||||
{ 0xFF0A /* Linefeed */, '\n' },
|
||||
{ 0xFF0B /* Vert. Tab */, '\v' },
|
||||
|
||||
#ifndef GDK_WINDOWING_WIN32
|
||||
{ 0xFF0D /* Return */, '\r' },
|
||||
{ 0xFF1B /* Escape */, '\033' },
|
||||
#endif
|
||||
|
||||
/* Numeric keypad */
|
||||
|
||||
@@ -868,7 +871,9 @@ static const struct {
|
||||
|
||||
/* End numeric keypad */
|
||||
|
||||
#ifndef GDK_WINDOWING_WIN32
|
||||
{ 0xFFFF /* Delete */, '\177' }
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1079,7 +1084,7 @@ static const struct {
|
||||
{ 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
|
||||
{ 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
|
||||
{ 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
|
||||
{ 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
|
||||
{ 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
|
||||
{ 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
|
||||
@@ -1394,7 +1399,6 @@ static const struct {
|
||||
{ 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */
|
||||
{ 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
|
||||
{ 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
|
||||
{ 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */
|
||||
{ 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
|
||||
{ 0x0aa2, 0x2002 }, /* enspace EN SPACE */
|
||||
{ 0x0aa1, 0x2003 }, /* emspace EM SPACE */
|
||||
@@ -1418,9 +1422,7 @@ static const struct {
|
||||
{ 0x0af1, 0x2020 }, /* dagger † DAGGER */
|
||||
{ 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
|
||||
{ 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
|
||||
{ 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */
|
||||
{ 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
|
||||
{ 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */
|
||||
{ 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
|
||||
{ 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
|
||||
{ 0x0afc, 0x2038 }, /* caret ‸ CARET */
|
||||
@@ -1478,8 +1480,7 @@ static const struct {
|
||||
{ 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
|
||||
{ 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
|
||||
{ 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
|
||||
{ 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */
|
||||
{ 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */
|
||||
{ 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
|
||||
{ 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
|
||||
{ 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
|
||||
{ 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
|
||||
@@ -1497,28 +1498,15 @@ static const struct {
|
||||
{ 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
|
||||
{ 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
|
||||
{ 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
|
||||
{ 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
|
||||
{ 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
|
||||
{ 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
|
||||
{ 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */
|
||||
{ 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */
|
||||
{ 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */
|
||||
{ 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */
|
||||
{ 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */
|
||||
{ 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */
|
||||
{ 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */
|
||||
{ 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */
|
||||
{ 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */
|
||||
{ 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */
|
||||
{ 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */
|
||||
{ 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */
|
||||
{ 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */
|
||||
{ 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */
|
||||
{ 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */
|
||||
{ 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
|
||||
{ 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */
|
||||
{ 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */
|
||||
{ 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */
|
||||
{ 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */
|
||||
{ 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */
|
||||
{ 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */
|
||||
{ 0x09e8, 0x2424 }, /* nl  SYMBOL FOR NEWLINE */
|
||||
{ 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
|
||||
{ 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
|
||||
@@ -1534,11 +1522,11 @@ static const struct {
|
||||
{ 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
|
||||
{ 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */
|
||||
{ 0x0adf, 0x25a0 }, /* emfilledrect ■ BLACK SQUARE */
|
||||
{ 0x0acf, 0x25a1 }, /* emopenrectangle □ WHITE SQUARE */
|
||||
{ 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */
|
||||
{ 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
|
||||
{ 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */
|
||||
{ 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */
|
||||
{ 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */
|
||||
{ 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */
|
||||
{ 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */
|
||||
{ 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
|
||||
@@ -1568,8 +1556,6 @@ static const struct {
|
||||
{ 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
|
||||
{ 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */
|
||||
{ 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
|
||||
{ 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */
|
||||
{ 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */
|
||||
{ 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */
|
||||
{ 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
|
||||
{ 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
|
||||
@@ -1688,7 +1674,6 @@ static const struct {
|
||||
{ 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
|
||||
{ 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
|
||||
{ 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
|
||||
{ 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */
|
||||
{ 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
|
||||
{ 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
|
||||
{ 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
|
||||
|
||||
@@ -133,10 +133,10 @@ gdk_memory_sanitize (GBytes *bytes,
|
||||
*
|
||||
* Creates a new texture for a blob of image data.
|
||||
*
|
||||
* The `GBytes` must contain @stride × @height pixels
|
||||
* The `GBytes` must contain @stride x @height pixels
|
||||
* in the given format.
|
||||
*
|
||||
* Returns: (type GdkMemoryTexture): A newly-created `GdkTexture`
|
||||
* Returns: A newly-created `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_memory_texture_new (int width,
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* Copyright (C) 2000 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
|
||||
@@ -52,25 +52,25 @@ layout_iter_get_line_clip_region (PangoLayoutIter *iter,
|
||||
|
||||
i = 0;
|
||||
while (i < n_ranges)
|
||||
{
|
||||
{
|
||||
int *pixel_ranges = NULL;
|
||||
int n_pixel_ranges = 0;
|
||||
int j;
|
||||
|
||||
/* Note that get_x_ranges returns layout coordinates
|
||||
*/
|
||||
if (index_ranges[i*2+1] >= pango_layout_line_get_start_index (line) &&
|
||||
index_ranges[i*2] < pango_layout_line_get_start_index (line) + pango_layout_line_get_length (line))
|
||||
if (index_ranges[i*2+1] >= line->start_index &&
|
||||
index_ranges[i*2] < line->start_index + line->length)
|
||||
pango_layout_line_get_x_ranges (line,
|
||||
index_ranges[i*2],
|
||||
index_ranges[i*2+1],
|
||||
&pixel_ranges, &n_pixel_ranges);
|
||||
|
||||
|
||||
for (j = 0; j < n_pixel_ranges; j++)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
int x_off, y_off;
|
||||
|
||||
|
||||
x_off = PANGO_PIXELS (pixel_ranges[2*j] - logical_rect.x);
|
||||
y_off = PANGO_PIXELS (baseline - logical_rect.y);
|
||||
|
||||
@@ -124,14 +124,14 @@ gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line,
|
||||
{
|
||||
cairo_region_t *clip_region;
|
||||
PangoLayoutIter *iter;
|
||||
|
||||
|
||||
g_return_val_if_fail (line != NULL, NULL);
|
||||
g_return_val_if_fail (index_ranges != NULL, NULL);
|
||||
|
||||
|
||||
iter = pango_layout_get_iter (line->layout);
|
||||
while (pango_layout_iter_get_line_readonly (iter) != line)
|
||||
pango_layout_iter_next_line (iter);
|
||||
|
||||
|
||||
clip_region = layout_iter_get_line_clip_region(iter, x_origin, y_origin, index_ranges, n_ranges);
|
||||
|
||||
pango_layout_iter_free (iter);
|
||||
@@ -167,26 +167,26 @@ gdk_pango_layout_get_clip_region (PangoLayout *layout,
|
||||
const int *index_ranges,
|
||||
int n_ranges)
|
||||
{
|
||||
PangoLayoutIter *iter;
|
||||
PangoLayoutIter *iter;
|
||||
cairo_region_t *clip_region;
|
||||
|
||||
|
||||
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
|
||||
g_return_val_if_fail (index_ranges != NULL, NULL);
|
||||
|
||||
|
||||
clip_region = cairo_region_create ();
|
||||
|
||||
|
||||
iter = pango_layout_get_iter (layout);
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
PangoRectangle logical_rect;
|
||||
cairo_region_t *line_region;
|
||||
int baseline;
|
||||
|
||||
|
||||
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
|
||||
baseline = pango_layout_iter_get_baseline (iter);
|
||||
baseline = pango_layout_iter_get_baseline (iter);
|
||||
|
||||
line_region = layout_iter_get_line_clip_region(iter,
|
||||
line_region = layout_iter_get_line_clip_region(iter,
|
||||
x_origin + PANGO_PIXELS (logical_rect.x),
|
||||
y_origin + PANGO_PIXELS (baseline),
|
||||
index_ranges,
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ gdk_popup_get_rect_anchor (GdkPopup *popup)
|
||||
*
|
||||
* Returns the parent surface of a popup.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the parent surface
|
||||
* Returns: (transfer none): the parent surface
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_popup_get_parent (GdkPopup *popup)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
((_GDK_RGBA_SELECT_COLOR(str, 0, 0) << 4) | _GDK_RGBA_SELECT_COLOR(str, 0, 1)) / 255., \
|
||||
((_GDK_RGBA_SELECT_COLOR(str, 1, 2) << 4) | _GDK_RGBA_SELECT_COLOR(str, 1, 3)) / 255., \
|
||||
((_GDK_RGBA_SELECT_COLOR(str, 2, 4) << 4) | _GDK_RGBA_SELECT_COLOR(str, 2, 5)) / 255., \
|
||||
((sizeof(str) % 4 == 1) ? ((_GDK_RGBA_SELECT_COLOR(str, 3, 6) << 4) | _GDK_RGBA_SELECT_COLOR(str, 3, 7)) : 0xFF) / 255. })
|
||||
((sizeof(str) % 4 == 1) ? ((_GDK_RGBA_SELECT_COLOR(str, 3, 6) << 4) | _GDK_RGBA_SELECT_COLOR(str, 3, 7)) : 0xFF) / 255 })
|
||||
|
||||
|
||||
gboolean gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
|
||||
+1
-11
@@ -1095,7 +1095,6 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
|
||||
|
||||
if (priv->egl_surface != NULL)
|
||||
{
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
@@ -1124,7 +1123,6 @@ gdk_surface_ensure_egl_surface (GdkSurface *self,
|
||||
priv->egl_surface != NULL &&
|
||||
gdk_display_get_egl_config_high_depth (display) != gdk_display_get_egl_config (display))
|
||||
{
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
@@ -2244,7 +2242,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
gulong serial)
|
||||
{
|
||||
GdkSurface *event_surface = NULL;
|
||||
GdkSurface *event_surface;
|
||||
gboolean unlink_event = FALSE;
|
||||
GdkDeviceGrabInfo *button_release_grab;
|
||||
GdkPointerSurfaceInfo *pointer_info = NULL;
|
||||
@@ -2336,14 +2334,6 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
||||
*/
|
||||
_gdk_event_queue_handle_motion_compression (display);
|
||||
gdk_event_queue_handle_scroll_compression (display);
|
||||
|
||||
if (event_surface)
|
||||
{
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (event_surface);
|
||||
|
||||
if (clock) /* might be NULL if surface was destroyed */
|
||||
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+10
-10
@@ -25,14 +25,14 @@
|
||||
* multiple frames, and will be used for a long time.
|
||||
*
|
||||
* There are various ways to create `GdkTexture` objects from a
|
||||
* [class@GdkPixbuf.Pixbuf], or a Cairo surface, or other pixel data.
|
||||
* `GdkPixbuf`, or a Cairo surface, or other pixel data.
|
||||
*
|
||||
* The ownership of the pixel data is transferred to the `GdkTexture`
|
||||
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].
|
||||
*
|
||||
* `GdkTexture` is an immutable object: That means you cannot change
|
||||
* anything about it other than increasing the reference count via
|
||||
* [method@GObject.Object.ref], and consequently, it is a thread-safe object.
|
||||
* g_object_ref().
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -346,7 +346,7 @@ gdk_texture_init (GdkTexture *self)
|
||||
*
|
||||
* Creates a new texture object representing the surface.
|
||||
*
|
||||
* @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
|
||||
* @surface must be an image surface with format CAIRO_FORMAT_ARGB32.
|
||||
*
|
||||
* Returns: a new `GdkTexture`
|
||||
*/
|
||||
@@ -384,7 +384,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
|
||||
* Creates a new texture object representing the `GdkPixbuf`.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Returns: a new `GdkTexture`
|
||||
@@ -430,7 +430,7 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
* [ctor@Gdk.Texture.new_from_file] to load it.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -454,7 +454,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
texture = NULL;
|
||||
|
||||
if (texture == NULL)
|
||||
g_error ("Resource path %s is not a valid image: %s", resource_path, error->message);
|
||||
g_error ("Resource path %s s not a valid image: %s", resource_path, error->message);
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -472,7 +472,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -565,7 +565,7 @@ gdk_texture_new_from_bytes_pixbuf (GBytes *bytes,
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -611,7 +611,7 @@ gdk_texture_new_from_bytes (GBytes *bytes,
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -796,7 +796,7 @@ gdk_texture_get_render_data (GdkTexture *self,
|
||||
*
|
||||
* This is a utility function intended for debugging and testing.
|
||||
* If you want more control over formats, proper error handling or
|
||||
* want to store to a [iface@Gio.File] or other location, you might want to
|
||||
* want to store to a `GFile` or other location, you might want to
|
||||
* use [method@Gdk.Texture.save_to_png_bytes] or look into the
|
||||
* gdk-pixbuf library.
|
||||
*
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkjpegprivate.h"
|
||||
|
||||
@@ -222,7 +222,11 @@ gdk_load_png (GBytes *bytes,
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
if (depth == 8)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8A8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_A8B8G8R8;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -232,7 +236,11 @@ gdk_load_png (GBytes *bytes,
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
if (depth == 8)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_B8G8R8;
|
||||
#endif
|
||||
}
|
||||
else if (depth == 16)
|
||||
{
|
||||
@@ -317,14 +325,22 @@ gdk_save_png (GdkTexture *texture)
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8A8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_A8B8G8R8;
|
||||
#endif
|
||||
png_format = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
depth = 8;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_B8G8R8;
|
||||
#endif
|
||||
png_format = PNG_COLOR_TYPE_RGB;
|
||||
depth = 8;
|
||||
break;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
#import "GdkMacosCairoView.h"
|
||||
|
||||
@@ -32,9 +33,7 @@
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_pointer (&self->clip, g_array_unref);
|
||||
g_clear_pointer (&self->damage, g_array_unref);
|
||||
g_clear_pointer (&self->image, CGImageRelease);
|
||||
g_clear_pointer (&self->clip, cairo_region_destroy);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -56,67 +55,132 @@
|
||||
-(void)drawRect:(NSRect)rect
|
||||
{
|
||||
CGContextRef cgContext;
|
||||
GdkSurface *gdk_surface;
|
||||
cairo_surface_t *dest;
|
||||
const NSRect *rects = NULL;
|
||||
NSView *root_view;
|
||||
CGRect image_rect;
|
||||
CGRect abs_bounds;
|
||||
NSInteger n_rects = 0;
|
||||
NSRect abs_bounds;
|
||||
cairo_t *cr;
|
||||
CGSize scale;
|
||||
int abs_height;
|
||||
int scale_factor;
|
||||
|
||||
if (self->image == NULL)
|
||||
if (self->cairoSurface == NULL)
|
||||
return;
|
||||
|
||||
cgContext = [[NSGraphicsContext currentContext] CGContext];
|
||||
/* Acquire everything we need to do translations, drawing, etc */
|
||||
gdk_surface = [self gdkSurface];
|
||||
scale_factor = gdk_surface_get_scale_factor (gdk_surface);
|
||||
root_view = [[self window] contentView];
|
||||
cgContext = [[NSGraphicsContext currentContext] CGContext];
|
||||
abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
abs_height = CGImageGetHeight (self->image);
|
||||
|
||||
CGContextSaveGState (cgContext);
|
||||
|
||||
/* Clip while our context is still using matching coordinates
|
||||
* to the self->clip region. This is usually just on the views
|
||||
* for the shadow areas.
|
||||
/* Translate scaling to remove HiDPI scaling from CGContext as
|
||||
* cairo will be doing that for us already.
|
||||
*/
|
||||
CGContextAddRect (cgContext, [self bounds]);
|
||||
if (self->clip != NULL)
|
||||
{
|
||||
for (guint i = 0; i < self->clip->len; i++)
|
||||
CGContextAddRect (cgContext, g_array_index (self->clip, CGRect, i));
|
||||
}
|
||||
if (self->damage != NULL)
|
||||
{
|
||||
for (guint i = 0; i < self->damage->len; i++)
|
||||
CGContextAddRect (cgContext, g_array_index (self->damage, CGRect, i));
|
||||
}
|
||||
CGContextClip (cgContext);
|
||||
|
||||
/* Scale/Translate so that the CGImageRef draws in proper format/placement */
|
||||
scale = CGSizeMake (1.0, 1.0);
|
||||
scale = CGContextConvertSizeToDeviceSpace (cgContext, scale);
|
||||
CGContextScaleCTM (cgContext, 1.0 / scale.width, 1.0 / scale.height);
|
||||
CGContextTranslateCTM (cgContext, -abs_bounds.origin.x, -abs_bounds.origin.y);
|
||||
image_rect = CGRectMake (-abs_bounds.origin.x,
|
||||
-abs_bounds.origin.y,
|
||||
CGImageGetWidth (self->image),
|
||||
CGImageGetHeight (self->image));
|
||||
CGContextDrawImage (cgContext, image_rect, self->image);
|
||||
|
||||
/* Create the cairo surface to draw to the CGContext and translate
|
||||
* coordinates so we can pretend we are in the same coordinate system
|
||||
* as the GDK surface.
|
||||
*/
|
||||
dest = cairo_quartz_surface_create_for_cg_context (cgContext,
|
||||
gdk_surface->width * scale_factor,
|
||||
gdk_surface->height * scale_factor);
|
||||
cairo_surface_set_device_scale (dest, scale_factor, scale_factor);
|
||||
|
||||
/* Create cairo context and translate things into the origin of
|
||||
* the topmost contentView so that we just draw at 0,0 with a
|
||||
* clip region to paint the surface.
|
||||
*/
|
||||
cr = cairo_create (dest);
|
||||
cairo_translate (cr, -abs_bounds.origin.x, -abs_bounds.origin.y);
|
||||
|
||||
/* Apply the clip if provided one */
|
||||
if (self->clip != NULL)
|
||||
{
|
||||
cairo_rectangle_int_t area;
|
||||
|
||||
n_rects = cairo_region_num_rectangles (self->clip);
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_region_get_rectangle (self->clip, i, &area);
|
||||
cairo_rectangle (cr, area.x, area.y, area.width, area.height);
|
||||
}
|
||||
|
||||
cairo_clip (cr);
|
||||
}
|
||||
|
||||
/* Clip the cairo context based on the rectangles to be drawn
|
||||
* within the bounding box :rect.
|
||||
*/
|
||||
[self getRectsBeingDrawn:&rects count:&n_rects];
|
||||
for (NSInteger i = 0; i < n_rects; i++)
|
||||
{
|
||||
NSRect area = [self convertRect:rects[i] toView:root_view];
|
||||
cairo_rectangle (cr,
|
||||
area.origin.x, area.origin.y,
|
||||
area.size.width, area.size.height);
|
||||
}
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Now paint the surface (without blending) as we do not need
|
||||
* any compositing here. The transparent regions (like shadows)
|
||||
* are already on non-opaque layers.
|
||||
*/
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface (cr, self->cairoSurface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
/* Cleanup state, flush the surface to the backing layer, and
|
||||
* restore GState for future use.
|
||||
*/
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_flush (dest);
|
||||
cairo_surface_destroy (dest);
|
||||
CGContextRestoreGState (cgContext);
|
||||
}
|
||||
|
||||
-(void)setImage:(CGImageRef)theImage
|
||||
withDamage:(cairo_region_t *)region
|
||||
-(void)setCairoSurface:(cairo_surface_t *)surface
|
||||
withDamage:(cairo_region_t *)region
|
||||
{
|
||||
if (theImage != image)
|
||||
if (surface != self->cairoSurface)
|
||||
{
|
||||
g_clear_pointer (&image, CGImageRelease);
|
||||
if (theImage)
|
||||
image = CGImageRetain (theImage);
|
||||
g_clear_pointer (&self->cairoSurface, cairo_surface_destroy);
|
||||
if (surface != NULL)
|
||||
self->cairoSurface = cairo_surface_reference (surface);
|
||||
}
|
||||
|
||||
[self convertRegion:region toArray:&self->damage andDisplay:YES];
|
||||
if (region != NULL)
|
||||
{
|
||||
NSView *root_view = [[self window] contentView];
|
||||
NSRect abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
guint n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
if (NSIntersectsRect (abs_bounds, nsrect))
|
||||
{
|
||||
nsrect.origin.x -= abs_bounds.origin.x;
|
||||
nsrect.origin.y -= abs_bounds.origin.y;
|
||||
[self setNeedsDisplayInRect:nsrect];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setImage:theImage withDamage:region];
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:surface
|
||||
withDamage:region];
|
||||
}
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque
|
||||
@@ -124,44 +188,14 @@
|
||||
self->_isOpaque = opaque;
|
||||
}
|
||||
|
||||
-(void)convertRegion:(const cairo_region_t *)region
|
||||
toArray:(GArray **)array
|
||||
andDisplay:(BOOL)display
|
||||
-(void)setClip:(cairo_region_t*)region
|
||||
{
|
||||
NSView *root_view;
|
||||
CGRect abs_bounds;
|
||||
guint n_rects;
|
||||
|
||||
if (*array == NULL)
|
||||
*array = g_array_new (FALSE, FALSE, sizeof (CGRect));
|
||||
else
|
||||
g_array_set_size (*array, 0);
|
||||
|
||||
root_view = [[self window] contentView];
|
||||
abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
if (region != self->clip)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
CGRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = CGRectIntersection (abs_bounds, CGRectMake (rect.x, rect.y, rect.width, rect.height));
|
||||
|
||||
if (!CGRectIsNull (nsrect))
|
||||
g_array_append_val (*array, nsrect);
|
||||
|
||||
if (display)
|
||||
[self setNeedsDisplayInRect:CGRectMake (rect.x - abs_bounds.origin.x,
|
||||
rect.y - abs_bounds.origin.y,
|
||||
rect.width, rect.height)];
|
||||
g_clear_pointer (&self->clip, cairo_region_destroy);
|
||||
if (region != NULL)
|
||||
self->clip = cairo_region_reference (region);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setClip:(cairo_region_t*)region
|
||||
{
|
||||
[self convertRegion:region toArray:&self->clip andDisplay:NO];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -19,21 +19,19 @@
|
||||
*/
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <cairo.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define GDK_IS_MACOS_CAIRO_SUBVIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoSubview class]])
|
||||
|
||||
@interface GdkMacosCairoSubview : NSView
|
||||
{
|
||||
BOOL _isOpaque;
|
||||
GArray *clip;
|
||||
GArray *damage;
|
||||
CGImageRef image;
|
||||
BOOL _isOpaque;
|
||||
cairo_surface_t *cairoSurface;
|
||||
cairo_region_t *clip;
|
||||
}
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque;
|
||||
-(void)setImage:(CGImageRef)theImage withDamage:(cairo_region_t *)region;
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)region;
|
||||
-(void)setClip:(cairo_region_t*)region;
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#import "GdkMacosCairoView.h"
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
@implementation GdkMacosCairoView
|
||||
@@ -59,92 +58,12 @@
|
||||
[child setNeedsDisplay:needsDisplay];
|
||||
}
|
||||
|
||||
static void
|
||||
release_surface_provider (void *info,
|
||||
const void *data,
|
||||
size_t size)
|
||||
{
|
||||
cairo_surface_destroy (info);
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)cairoRegion
|
||||
{
|
||||
CGImageRef image = NULL;
|
||||
|
||||
if (cairoSurface != NULL)
|
||||
{
|
||||
const CGColorRenderingIntent intent = kCGRenderingIntentDefault;
|
||||
CGDataProviderRef provider;
|
||||
CGColorSpaceRef rgb;
|
||||
cairo_format_t format;
|
||||
CGBitmapInfo bitmap = kCGBitmapByteOrder32Host;
|
||||
GdkMonitor *monitor;
|
||||
guint8 *framebuffer;
|
||||
size_t width;
|
||||
size_t height;
|
||||
int rowstride;
|
||||
int bpp;
|
||||
int bpc;
|
||||
|
||||
cairo_surface_flush (cairoSurface);
|
||||
|
||||
format = cairo_image_surface_get_format (cairoSurface);
|
||||
framebuffer = cairo_image_surface_get_data (cairoSurface);
|
||||
rowstride = cairo_image_surface_get_stride (cairoSurface);
|
||||
width = cairo_image_surface_get_width (cairoSurface);
|
||||
height = cairo_image_surface_get_height (cairoSurface);
|
||||
monitor = _gdk_macos_surface_get_best_monitor ([self gdkSurface]);
|
||||
rgb = _gdk_macos_monitor_copy_colorspace (GDK_MACOS_MONITOR (monitor));
|
||||
|
||||
/* If we have an WCG colorspace, just take the slow path or we risk
|
||||
* really screwing things up.
|
||||
*/
|
||||
if (CGColorSpaceIsWideGamutRGB (rgb))
|
||||
{
|
||||
CGColorSpaceRelease (rgb);
|
||||
rgb = CGColorSpaceCreateDeviceRGB ();
|
||||
}
|
||||
|
||||
/* Assert that our image surface was created correctly with
|
||||
* 16-byte aligned pointers and strides. This is needed to
|
||||
* ensure that we're working with fast paths in CoreGraphics.
|
||||
*/
|
||||
g_assert (format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24);
|
||||
g_assert (framebuffer != NULL);
|
||||
g_assert (((intptr_t)framebuffer & (intptr_t)~0xF) == (intptr_t)framebuffer);
|
||||
g_assert ((rowstride & ~0xF) == rowstride);
|
||||
|
||||
if (format == CAIRO_FORMAT_ARGB32)
|
||||
{
|
||||
bitmap |= kCGImageAlphaPremultipliedFirst;
|
||||
bpp = 32;
|
||||
bpc = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap |= kCGImageAlphaNoneSkipFirst;
|
||||
bpp = 32;
|
||||
bpc = 8;
|
||||
}
|
||||
|
||||
provider = CGDataProviderCreateWithData (cairo_surface_reference (cairoSurface),
|
||||
framebuffer,
|
||||
rowstride * height,
|
||||
release_surface_provider);
|
||||
|
||||
image = CGImageCreate (width, height, bpc, bpp, rowstride, rgb, bitmap, provider, NULL, FALSE, intent);
|
||||
|
||||
CGDataProviderRelease (provider);
|
||||
CGColorSpaceRelease (rgb);
|
||||
}
|
||||
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setImage:image
|
||||
withDamage:cairoRegion];
|
||||
|
||||
if (image != NULL)
|
||||
CGImageRelease (image);
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:cairoSurface
|
||||
withDamage:cairoRegion];
|
||||
}
|
||||
|
||||
-(void)removeOpaqueChildren
|
||||
@@ -243,6 +162,7 @@ release_surface_provider (void *info,
|
||||
*/
|
||||
self->transparent = [[GdkMacosCairoSubview alloc] initWithFrame:frame];
|
||||
[self addSubview:self->transparent];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -214,14 +214,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
* as we are leaving maximized state.
|
||||
*/
|
||||
if ((style_mask & NSWindowStyleMaskTitled) == 0 && [self isOpaque])
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE ([self gdkSurface]);
|
||||
|
||||
[self setOpaque:NO];
|
||||
|
||||
/* Force updating of various styling, regions, etc */
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
[self setOpaque:NO];
|
||||
}
|
||||
|
||||
-(void)windowDidMove:(NSNotification *)aNotification
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "gdkdisplaylinksource.h"
|
||||
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
static gint64 host_to_frame_clock_time (gint64 val);
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ struct _GdkMacosCairoContext
|
||||
GdkCairoContext parent_instance;
|
||||
|
||||
cairo_surface_t *window_surface;
|
||||
cairo_t *cr;
|
||||
};
|
||||
|
||||
struct _GdkMacosCairoContextClass
|
||||
@@ -47,66 +46,30 @@ G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CO
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_surface (GdkSurface *surface)
|
||||
{
|
||||
static const cairo_user_data_key_t buffer_key;
|
||||
cairo_surface_t *cairo_surface;
|
||||
guint8 *data;
|
||||
cairo_format_t format;
|
||||
size_t size;
|
||||
size_t rowstride;
|
||||
size_t width;
|
||||
size_t height;
|
||||
int scale;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
/* We use a cairo image surface here instead of a quartz surface because
|
||||
* we get strange artifacts with the quartz surface such as empty
|
||||
* cross-fades when hovering buttons. For performance, we want to be using
|
||||
* GL rendering so there isn't much point here as correctness is better.
|
||||
*
|
||||
* Additionally, so we can take avantage of faster paths in Core
|
||||
* Graphics, we want our data pointer to be 16-byte aligned and our rows
|
||||
* to be 16-byte aligned or we risk errors below us. Normally, cairo
|
||||
* image surface does not guarantee the later, which means we could end
|
||||
* up doing some costly copies along the way to compositing.
|
||||
*/
|
||||
|
||||
if ([GDK_MACOS_SURFACE (surface)->window isOpaque])
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
else
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
width = scale * gdk_surface_get_width (surface);
|
||||
height = scale * gdk_surface_get_height (surface);
|
||||
rowstride = (cairo_format_stride_for_width (format, width) + 0xF) & ~0xF;
|
||||
size = rowstride * height;
|
||||
data = g_malloc0 (size);
|
||||
cairo_surface = cairo_image_surface_create_for_data (data, format, width, height, rowstride);
|
||||
cairo_surface_set_user_data (cairo_surface, &buffer_key, data, g_free);
|
||||
cairo_surface_set_device_scale (cairo_surface, scale, scale);
|
||||
|
||||
/* We use a cairo image surface here instead of a quartz surface because we
|
||||
* get strange artifacts with the quartz surface such as empty cross-fades
|
||||
* when hovering buttons. For performance, we want to be using GL rendering
|
||||
* so there isn't much point here as correctness is better.
|
||||
*/
|
||||
cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
|
||||
if (cairo_surface != NULL)
|
||||
cairo_surface_set_device_scale (cairo_surface, scale, scale);
|
||||
|
||||
return cairo_surface;
|
||||
}
|
||||
|
||||
static cairo_t *
|
||||
do_cairo_create (GdkMacosCairoContext *self)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
|
||||
cr = cairo_create (self->window_surface);
|
||||
|
||||
/* Draw upside down as quartz prefers */
|
||||
cairo_translate (cr, 0, surface->height);
|
||||
cairo_scale (cr, 1.0, -1.0);
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
static cairo_t *
|
||||
_gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
|
||||
{
|
||||
@@ -114,10 +77,7 @@ _gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
if (self->cr != NULL)
|
||||
return cairo_reference (self->cr);
|
||||
|
||||
return do_cairo_create (self);
|
||||
return cairo_create (self->window_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -135,18 +95,20 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
if (self->window_surface == NULL)
|
||||
self->window_surface = create_cairo_surface_for_surface (surface);
|
||||
|
||||
self->cr = do_cairo_create (self);
|
||||
|
||||
if (![nswindow isOpaque])
|
||||
{
|
||||
cairo_save (self->cr);
|
||||
gdk_cairo_region (self->cr, region);
|
||||
cairo_set_source_rgba (self->cr, 0, 0, 0, 0);
|
||||
cairo_set_operator (self->cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_fill (self->cr);
|
||||
cairo_restore (self->cr);
|
||||
self->window_surface = create_cairo_surface_for_surface (surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (![nswindow isOpaque])
|
||||
{
|
||||
cairo_t *cr = cairo_create (self->window_surface);
|
||||
gdk_cairo_region (cr, region);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_fill (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +126,6 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
g_clear_pointer (&self->cr, cairo_destroy);
|
||||
|
||||
if (GDK_IS_MACOS_CAIRO_VIEW (nsview))
|
||||
[(GdkMacosCairoView *)nsview setCairoSurface:self->window_surface
|
||||
withDamage:painted];
|
||||
@@ -181,25 +141,12 @@ _gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_dispose (GObject *object)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)object;
|
||||
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_macos_cairo_context_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_class_init (GdkMacosCairoContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkCairoContextClass *cairo_context_class = GDK_CAIRO_CONTEXT_CLASS (klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||
|
||||
object_class->dispose = _gdk_macos_cairo_context_dispose;
|
||||
|
||||
draw_context_class->begin_frame = _gdk_macos_cairo_context_begin_frame;
|
||||
draw_context_class->end_frame = _gdk_macos_cairo_context_end_frame;
|
||||
draw_context_class->surface_resized = _gdk_macos_cairo_context_surface_resized;
|
||||
|
||||
@@ -537,7 +537,6 @@ fill_pinch_event (GdkMacosDisplay *display,
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
|
||||
|
||||
return gdk_touchpad_event_new_pinch (GDK_SURFACE (surface),
|
||||
NULL, /* FIXME make up sequences */
|
||||
gdk_seat_get_pointer (seat),
|
||||
get_time_from_ns_event (nsevent),
|
||||
get_keyboard_modifiers_from_ns_event (nsevent),
|
||||
|
||||
@@ -301,14 +301,10 @@ gdk_macos_display_frame_cb (gpointer data)
|
||||
|
||||
iter = iter->next;
|
||||
|
||||
_gdk_macos_surface_publish_timings (surface,
|
||||
source->presentation_time,
|
||||
source->refresh_interval);
|
||||
|
||||
_gdk_macos_display_remove_frame_callback (self, surface);
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface)))
|
||||
gdk_surface_thaw_updates (GDK_SURFACE (surface));
|
||||
_gdk_macos_surface_thaw (surface,
|
||||
source->presentation_time,
|
||||
source->refresh_interval);
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
@@ -730,8 +726,7 @@ _gdk_macos_display_open (const char *display_name)
|
||||
if (self != NULL)
|
||||
return NULL;
|
||||
|
||||
display_name = display_name ? display_name : "";
|
||||
GDK_NOTE (MISC, g_message ("opening display %s", display_name));
|
||||
GDK_NOTE (MISC, g_message ("opening display %s", display_name ? display_name : ""));
|
||||
|
||||
/* Make the current process a foreground application, i.e. an app
|
||||
* with a user interface, in case we're not running from a .app bundle
|
||||
@@ -992,11 +987,7 @@ _gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
|
||||
|
||||
if (!queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
{
|
||||
/* Processing frames is always head to tail, so push to the
|
||||
* head so that we don't possibly re-enter this right after
|
||||
* adding to the queue.
|
||||
*/
|
||||
g_queue_push_head_link (&self->awaiting_frames, &surface->frame);
|
||||
g_queue_push_tail_link (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
if (self->awaiting_frames.length == 1)
|
||||
gdk_display_link_source_unpause ((GdkDisplayLinkSource *)self->frame_source);
|
||||
|
||||
@@ -29,11 +29,10 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
|
||||
CGDirectDisplayID screen_id);
|
||||
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
|
||||
gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
|
||||
CGColorSpaceRef _gdk_macos_monitor_copy_colorspace (GdkMacosMonitor *self);
|
||||
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
|
||||
CGDirectDisplayID screen_id);
|
||||
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
|
||||
gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -298,11 +298,3 @@ _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self)
|
||||
|
||||
return self->screen_id;
|
||||
}
|
||||
|
||||
CGColorSpaceRef
|
||||
_gdk_macos_monitor_copy_colorspace (GdkMacosMonitor *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_MONITOR (self), NULL);
|
||||
|
||||
return CGDisplayCopyColorSpace (self->screen_id);
|
||||
}
|
||||
|
||||
@@ -204,10 +204,6 @@ static void
|
||||
_gdk_macos_popup_surface_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosPopupSurface *self = (GdkMacosPopupSurface *)object;
|
||||
GdkSurface *parent = GDK_SURFACE (self)->parent;
|
||||
|
||||
if (parent != NULL)
|
||||
parent->children = g_list_remove (parent->children, self);
|
||||
|
||||
g_clear_object (&GDK_SURFACE (self)->parent);
|
||||
g_clear_pointer (&self->layout, gdk_popup_layout_unref);
|
||||
|
||||
@@ -104,7 +104,7 @@ void _gdk_macos_surface_resize (GdkMacosSurface
|
||||
void _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_update_position (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_show (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_publish_timings (GdkMacosSurface *self,
|
||||
void _gdk_macos_surface_thaw (GdkMacosSurface *self,
|
||||
gint64 predicted_presentation_time,
|
||||
gint64 refresh_interval);
|
||||
CGContextRef _gdk_macos_surface_acquire_context (GdkMacosSurface *self,
|
||||
|
||||
+13
-24
@@ -125,8 +125,6 @@ gdk_macos_surface_hide (GdkSurface *surface)
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
_gdk_macos_display_remove_frame_callback (GDK_MACOS_DISPLAY (surface->display), self);
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
|
||||
|
||||
seat = gdk_display_get_default_seat (surface->display);
|
||||
@@ -192,20 +190,15 @@ gdk_macos_surface_end_frame (GdkMacosSurface *self)
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
display = gdk_surface_get_display (GDK_SURFACE (self));
|
||||
frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self));
|
||||
|
||||
if ((timings = gdk_frame_clock_get_current_timings (frame_clock)))
|
||||
self->pending_frame_counter = timings->frame_counter;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
|
||||
{
|
||||
_gdk_macos_display_add_frame_callback (GDK_MACOS_DISPLAY (display), self);
|
||||
gdk_surface_freeze_updates (GDK_SURFACE (self));
|
||||
}
|
||||
_gdk_macos_display_add_frame_callback (GDK_MACOS_DISPLAY (display), self);
|
||||
|
||||
gdk_surface_freeze_updates (GDK_SURFACE (self));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -217,11 +210,10 @@ gdk_macos_surface_before_paint (GdkMacosSurface *self,
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
g_assert (GDK_IS_FRAME_CLOCK (frame_clock));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
if (surface->update_freeze_count > 0)
|
||||
return;
|
||||
|
||||
if (surface->update_freeze_count == 0)
|
||||
gdk_macos_surface_begin_frame (self);
|
||||
gdk_macos_surface_begin_frame (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -233,11 +225,10 @@ gdk_macos_surface_after_paint (GdkMacosSurface *self,
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
g_assert (GDK_IS_FRAME_CLOCK (frame_clock));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
if (surface->update_freeze_count > 0)
|
||||
return;
|
||||
|
||||
if (surface->update_freeze_count == 0)
|
||||
gdk_macos_surface_end_frame (self);
|
||||
gdk_macos_surface_end_frame (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -724,17 +715,18 @@ _gdk_macos_surface_update_position (GdkMacosSurface *self)
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_surface_publish_timings (GdkMacosSurface *self,
|
||||
gint64 presentation_time,
|
||||
gint64 refresh_interval)
|
||||
_gdk_macos_surface_thaw (GdkMacosSurface *self,
|
||||
gint64 presentation_time,
|
||||
gint64 refresh_interval)
|
||||
{
|
||||
GdkFrameTimings *timings;
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (!(frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self))))
|
||||
return;
|
||||
gdk_surface_thaw_updates (GDK_SURFACE (self));
|
||||
|
||||
frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self));
|
||||
|
||||
if (self->pending_frame_counter)
|
||||
{
|
||||
@@ -994,9 +986,6 @@ _gdk_macos_surface_monitor_changed (GdkMacosSurface *self)
|
||||
|
||||
g_object_unref (monitor);
|
||||
}
|
||||
|
||||
_gdk_surface_update_size (GDK_SURFACE (self));
|
||||
gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
|
||||
}
|
||||
|
||||
GdkMonitor *
|
||||
|
||||
@@ -181,8 +181,8 @@ gdk_wayland_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
GdkWaylandCairoContext *self = GDK_WAYLAND_CAIRO_CONTEXT (draw_context);
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_attach_image (surface, self->paint_surface, painted);
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
|
||||
|
||||
@@ -137,7 +137,6 @@ struct _GdkWaylandPointerData {
|
||||
guint cursor_timeout_id;
|
||||
guint cursor_image_index;
|
||||
guint cursor_image_delay;
|
||||
guint touchpad_event_sequence;
|
||||
|
||||
guint current_output_scale;
|
||||
GSList *pointer_surface_outputs;
|
||||
@@ -227,7 +226,6 @@ struct _GdkWaylandSeat
|
||||
struct wl_touch *wl_touch;
|
||||
struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe;
|
||||
struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch;
|
||||
struct zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold;
|
||||
struct zwp_tablet_seat_v2 *wp_tablet_seat;
|
||||
|
||||
GdkDisplay *display;
|
||||
@@ -1129,7 +1127,7 @@ data_offer_source_actions (void *data,
|
||||
seat->pending_source_actions = gdk_wayland_actions_to_gdk_actions (source_actions);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
@@ -1154,7 +1152,7 @@ data_offer_action (void *data,
|
||||
seat->pending_action = gdk_wayland_actions_to_gdk_actions (action);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
@@ -2166,7 +2164,7 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
key,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
_gdk_wayland_keymap_key_is_modifier (keymap, key),
|
||||
&translated,
|
||||
&translated,
|
||||
&no_lock);
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
@@ -2669,11 +2667,7 @@ emit_gesture_swipe_event (GdkWaylandSeat *seat,
|
||||
|
||||
seat->pointer_info.time = _time;
|
||||
|
||||
if (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN)
|
||||
seat->pointer_info.touchpad_event_sequence++;
|
||||
|
||||
event = gdk_touchpad_event_new_swipe (seat->pointer_info.focus,
|
||||
GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence),
|
||||
seat->logical_pointer,
|
||||
_time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
@@ -2769,11 +2763,7 @@ emit_gesture_pinch_event (GdkWaylandSeat *seat,
|
||||
|
||||
seat->pointer_info.time = _time;
|
||||
|
||||
if (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN)
|
||||
seat->pointer_info.touchpad_event_sequence++;
|
||||
|
||||
event = gdk_touchpad_event_new_pinch (seat->pointer_info.focus,
|
||||
GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence),
|
||||
seat->logical_pointer,
|
||||
_time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
@@ -2857,81 +2847,6 @@ gesture_pinch_end (void *data,
|
||||
0, 0, 1, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_gesture_hold_event (GdkWaylandSeat *seat,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
guint32 _time,
|
||||
guint32 n_fingers)
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
if (!seat->pointer_info.focus)
|
||||
return;
|
||||
|
||||
seat->pointer_info.time = _time;
|
||||
|
||||
event = gdk_touchpad_event_new_hold (seat->pointer_info.focus,
|
||||
seat->logical_pointer,
|
||||
_time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
phase,
|
||||
seat->pointer_info.surface_x,
|
||||
seat->pointer_info.surface_y,
|
||||
n_fingers);
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_seat_get_display (GDK_SEAT (seat)), EVENTS))
|
||||
{
|
||||
double x, y;
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
g_message ("hold event %d, coords: %f %f, seat %p state %d",
|
||||
gdk_event_get_event_type (event),
|
||||
x, y, seat,
|
||||
gdk_event_get_modifier_state (event));
|
||||
}
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_hold_begin (void *data,
|
||||
struct zwp_pointer_gesture_hold_v1 *hold,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
struct wl_surface *surface,
|
||||
uint32_t fingers)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
emit_gesture_hold_event (seat,
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_BEGIN,
|
||||
time, fingers);
|
||||
seat->gesture_n_fingers = fingers;
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_hold_end (void *data,
|
||||
struct zwp_pointer_gesture_hold_v1 *hold,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t cancelled)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkTouchpadGesturePhase phase;
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
phase = (cancelled) ?
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_CANCEL :
|
||||
GDK_TOUCHPAD_GESTURE_PHASE_END;
|
||||
|
||||
emit_gesture_hold_event (seat, phase, time,
|
||||
seat->gesture_n_fingers);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_wayland_seat_remove_tool (GdkWaylandSeat *seat,
|
||||
GdkWaylandTabletToolData *tool)
|
||||
@@ -3141,11 +3056,6 @@ static const struct zwp_pointer_gesture_pinch_v1_listener gesture_pinch_listener
|
||||
gesture_pinch_end
|
||||
};
|
||||
|
||||
static const struct zwp_pointer_gesture_hold_v1_listener gesture_hold_listener = {
|
||||
gesture_hold_begin,
|
||||
gesture_hold_end
|
||||
};
|
||||
|
||||
static const struct zwp_tablet_v2_listener tablet_listener = {
|
||||
tablet_handle_name,
|
||||
tablet_handle_id,
|
||||
@@ -3201,17 +3111,6 @@ seat_handle_capabilities (void *data,
|
||||
seat);
|
||||
zwp_pointer_gesture_pinch_v1_add_listener (seat->wp_pointer_gesture_pinch,
|
||||
&gesture_pinch_listener, seat);
|
||||
|
||||
if (display_wayland->pointer_gestures_version >= ZWP_POINTER_GESTURES_V1_GET_HOLD_GESTURE_SINCE_VERSION)
|
||||
{
|
||||
seat->wp_pointer_gesture_hold =
|
||||
zwp_pointer_gestures_v1_get_hold_gesture (display_wayland->pointer_gestures,
|
||||
seat->wl_pointer);
|
||||
zwp_pointer_gesture_hold_v1_set_user_data (seat->wp_pointer_gesture_hold,
|
||||
seat);
|
||||
zwp_pointer_gesture_hold_v1_add_listener (seat->wp_pointer_gesture_hold,
|
||||
&gesture_hold_listener, seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer)
|
||||
@@ -4189,7 +4088,7 @@ tablet_pad_strip_handle_frame (void *data,
|
||||
event = gdk_pad_event_new_strip (seat->keyboard_focus,
|
||||
pad->device,
|
||||
time,
|
||||
g_list_index (pad->mode_groups, group),
|
||||
g_list_index (pad->mode_groups, group),
|
||||
g_list_index (pad->strips, wp_tablet_pad_strip),
|
||||
group->current_mode,
|
||||
group->axis_tmp_info.value);
|
||||
|
||||
@@ -366,8 +366,7 @@ gdk_registry_handle_global (void *data,
|
||||
if (strcmp (interface, "wl_compositor") == 0)
|
||||
{
|
||||
display_wayland->compositor =
|
||||
wl_registry_bind (display_wayland->wl_registry, id,
|
||||
&wl_compositor_interface, MIN (version, 5));
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_compositor_interface, MIN (version, 4));
|
||||
display_wayland->compositor_version = MIN (version, 4);
|
||||
}
|
||||
else if (strcmp (interface, "wl_shm") == 0)
|
||||
@@ -431,9 +430,6 @@ gdk_registry_handle_global (void *data,
|
||||
}
|
||||
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0)
|
||||
{
|
||||
display_wayland->pointer_gestures_version =
|
||||
MIN (version, GDK_ZWP_POINTER_GESTURES_V1_VERSION);
|
||||
|
||||
display_wayland->pointer_gestures =
|
||||
wl_registry_bind (display_wayland->wl_registry,
|
||||
id, &zwp_pointer_gestures_v1_interface,
|
||||
@@ -1666,7 +1662,6 @@ static TranslationEntry translations[] = {
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
||||
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.a11y.interface", "high-contrast", "high-contast", G_TYPE_NONE, { .b = FALSE } },
|
||||
/* Note, this setting doesn't exist, the portal and gsd fake it */
|
||||
{ FALSE, "org.gnome.fontconfig", "serial", "gtk-fontconfig-timestamp", G_TYPE_NONE, { .i = 0 } },
|
||||
};
|
||||
@@ -1716,13 +1711,6 @@ find_translation_entry_by_setting (const char *setting)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
high_contrast_changed (GdkDisplay *display)
|
||||
{
|
||||
gdk_display_setting_changed (display, "gtk-theme-name");
|
||||
gdk_display_setting_changed (display, "gtk-icon-theme-name");
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
@@ -1736,8 +1724,6 @@ settings_changed (GSettings *settings,
|
||||
{
|
||||
if (entry->type != G_TYPE_NONE)
|
||||
gdk_display_setting_changed (display, entry->setting);
|
||||
else if (strcmp (key, "high-contrast") == 0)
|
||||
high_contrast_changed (display);
|
||||
else
|
||||
update_xft_settings (display);
|
||||
}
|
||||
@@ -2104,36 +2090,6 @@ set_decoration_layout_from_entry (GdkDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_theme_from_entry (GdkDisplay *display,
|
||||
TranslationEntry *entry,
|
||||
GValue *value)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GSettings *settings = NULL;
|
||||
GSettingsSchema *schema = NULL;
|
||||
gboolean hc = FALSE;
|
||||
|
||||
if (display_wayland->settings_portal == NULL)
|
||||
{
|
||||
settings = (GSettings *)g_hash_table_lookup (display_wayland->settings,
|
||||
"org.gnome.desktop.a11y.interface");
|
||||
}
|
||||
|
||||
if (settings)
|
||||
g_object_get (settings, "settings-schema", &schema, NULL);
|
||||
|
||||
if (schema && g_settings_schema_has_key (schema, "high-contrast"))
|
||||
hc = g_settings_get_boolean (settings, "high-contrast");
|
||||
|
||||
g_clear_pointer (&schema, g_settings_schema_unref);
|
||||
|
||||
if (hc)
|
||||
g_value_set_static_string (value, "HighContrast");
|
||||
else
|
||||
set_value_from_entry (display, entry, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_capability_setting (GdkDisplay *display,
|
||||
GValue *value,
|
||||
@@ -2165,9 +2121,6 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
|
||||
{
|
||||
if (strcmp (name, "gtk-decoration-layout") == 0)
|
||||
set_decoration_layout_from_entry (display, entry, value);
|
||||
else if (strcmp (name, "gtk-theme-name") == 0 ||
|
||||
strcmp (name, "gtk-icon-theme-name") == 0)
|
||||
set_theme_from_entry (display, entry, value);
|
||||
else
|
||||
set_value_from_entry (display, entry, value);
|
||||
return TRUE;
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_ZWP_POINTER_GESTURES_V1_VERSION 3
|
||||
#define GDK_ZWP_POINTER_GESTURES_V1_VERSION 1
|
||||
|
||||
typedef struct _GdkWaylandSelection GdkWaylandSelection;
|
||||
|
||||
@@ -140,7 +140,6 @@ struct _GdkWaylandDisplay
|
||||
int data_device_manager_version;
|
||||
int gtk_shell_version;
|
||||
int xdg_output_manager_version;
|
||||
int pointer_gestures_version;
|
||||
int xdg_activation_version;
|
||||
|
||||
uint32_t server_decoration_mode;
|
||||
|
||||
@@ -101,7 +101,6 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
|
||||
{
|
||||
GDK_DISPLAY_NOTE (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, g_message ("%p: Ignoring clipboard offer for self", cb));
|
||||
gdk_content_formats_unref (formats);
|
||||
g_clear_pointer (&offer, zwp_primary_selection_offer_v1_destroy);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ struct _GdkWaylandSurface
|
||||
unsigned int mapped : 1;
|
||||
unsigned int awaiting_frame : 1;
|
||||
unsigned int awaiting_frame_frozen : 1;
|
||||
unsigned int is_drag_surface : 1;
|
||||
|
||||
int pending_buffer_offset_x;
|
||||
int pending_buffer_offset_y;
|
||||
@@ -779,22 +780,11 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!impl->display_server.outputs)
|
||||
scale = 1;
|
||||
for (l = impl->display_server.outputs; l != NULL; l = l->next)
|
||||
{
|
||||
scale = impl->scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = 1;
|
||||
for (l = impl->display_server.outputs; l != NULL; l = l->next)
|
||||
{
|
||||
struct wl_output *output = l->data;
|
||||
uint32_t output_scale;
|
||||
|
||||
output_scale = gdk_wayland_display_get_output_scale (display_wayland,
|
||||
output);
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
guint32 output_scale = gdk_wayland_display_get_output_scale (display_wayland, l->data);
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
/* Notify app that scale changed */
|
||||
@@ -935,33 +925,12 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_sync_offset (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (wl_surface_get_version (impl->display_server.wl_surface) <
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
return;
|
||||
|
||||
if (impl->pending_buffer_offset_x == 0 &&
|
||||
impl->pending_buffer_offset_y == 0)
|
||||
return;
|
||||
|
||||
wl_surface_offset (impl->display_server.wl_surface,
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_surface_sync (GdkSurface *surface)
|
||||
{
|
||||
gdk_wayland_surface_sync_shadow (surface);
|
||||
gdk_wayland_surface_sync_opaque_region (surface);
|
||||
gdk_wayland_surface_sync_input_region (surface);
|
||||
gdk_wayland_surface_sync_offset (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1498,7 +1467,6 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
|
||||
int width, height;
|
||||
gboolean is_resizing;
|
||||
gboolean fixed_size;
|
||||
gboolean was_fixed_size;
|
||||
gboolean saved_size;
|
||||
|
||||
new_state = impl->pending.toplevel.state;
|
||||
@@ -1513,11 +1481,6 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
|
||||
GDK_TOPLEVEL_STATE_TILED) ||
|
||||
is_resizing;
|
||||
|
||||
was_fixed_size =
|
||||
surface->state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
|
||||
GDK_TOPLEVEL_STATE_FULLSCREEN |
|
||||
GDK_TOPLEVEL_STATE_TILED);
|
||||
|
||||
width = impl->pending.toplevel.width;
|
||||
height = impl->pending.toplevel.height;
|
||||
|
||||
@@ -1530,7 +1493,7 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
|
||||
* the client should configure its size back to what it was before
|
||||
* being maximize or fullscreen.
|
||||
*/
|
||||
if (saved_size && !fixed_size && was_fixed_size)
|
||||
if (saved_size && !fixed_size)
|
||||
{
|
||||
width = impl->saved_width;
|
||||
height = impl->saved_height;
|
||||
@@ -2320,7 +2283,8 @@ gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel)
|
||||
|
||||
if (!wayland_toplevel->idle_inhibitor)
|
||||
{
|
||||
g_assert (wayland_toplevel->idle_inhibitor_refcount == 0);
|
||||
g_assert (wayland_toplevel->idle_inhibitor &&
|
||||
wayland_toplevel->idle_inhibitor_refcount > 0);
|
||||
|
||||
wayland_toplevel->idle_inhibitor =
|
||||
zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager,
|
||||
@@ -2861,12 +2825,27 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_be_mapped (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
/* Don't map crazy temp that GTK uses for internal X11 shenanigans. */
|
||||
if (GDK_IS_DRAG_SURFACE (surface) && surface->x < 0 && surface->y < 0)
|
||||
return FALSE;
|
||||
|
||||
if (impl->is_drag_surface)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_map_toplevel (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!GDK_IS_WAYLAND_TOPLEVEL (surface))
|
||||
if (!should_be_mapped (surface))
|
||||
return;
|
||||
|
||||
if (impl->mapped)
|
||||
@@ -4724,6 +4703,7 @@ create_dnd_surface (GdkDisplay *display)
|
||||
GDK_SURFACE_TEMP,
|
||||
NULL,
|
||||
0, 0, 100, 100);
|
||||
GDK_WAYLAND_SURFACE (surface)->is_drag_surface = TRUE;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ foreach p: proto_sources
|
||||
elif proto_stability == 'staging'
|
||||
proto_version = p.get(2)
|
||||
output_base = '@0@-@1@'.format(proto_name, proto_version)
|
||||
input = files(join_paths(wlproto_dir, '@0@/@1@/@2@.xml'.format(proto_stability, proto_name, output_base)))
|
||||
input = join_paths(wlproto_dir, '@0@/@1@/@2@.xml'.format(proto_stability, proto_name, output_base))
|
||||
elif proto_stability == 'private'
|
||||
output_base = proto_name
|
||||
input = files('protocol/@0@.xml'.format(proto_name))
|
||||
|
||||
@@ -0,0 +1,406 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2001 Stefan Ondrejicka
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int id;
|
||||
char *bitmap;
|
||||
int hotx;
|
||||
int hoty;
|
||||
} font_info_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int id;
|
||||
int width;
|
||||
int height;
|
||||
int hotx;
|
||||
int hoty;
|
||||
char *data;
|
||||
} cursor_info_t;
|
||||
|
||||
static GSList *fonts = NULL;
|
||||
static GSList *cursors = NULL;
|
||||
|
||||
static int dw,dh;
|
||||
|
||||
static gboolean debug = FALSE;
|
||||
|
||||
#define HEX(c) (((c) >= '0' && (c) <= '9') ? \
|
||||
((c) - '0') : (toupper(c) - 'A' + 10))
|
||||
|
||||
static void print_font(fi)
|
||||
font_info_t *fi;
|
||||
{
|
||||
int x,y;
|
||||
|
||||
for (y = 0; y < dh; y++)
|
||||
{
|
||||
for (x = 0; x < dw; x++)
|
||||
{
|
||||
printf(fi->bitmap[y*dw+x]? "X" : " ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_cursor(ci)
|
||||
cursor_info_t *ci;
|
||||
{
|
||||
int x,y;
|
||||
|
||||
for (y = 0; y < ci->height; y++)
|
||||
{
|
||||
printf("/* ");
|
||||
for (x = 0; x < ci->width; x++)
|
||||
{
|
||||
if (ci->hotx == x && ci->hoty == y)
|
||||
printf("o");
|
||||
else
|
||||
switch (ci->data[y*ci->width+x])
|
||||
{
|
||||
case 0:
|
||||
printf(" ");
|
||||
break;
|
||||
case 1:
|
||||
printf(".");
|
||||
break;
|
||||
case 2:
|
||||
printf("X");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf(" */\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int read_bdf_font(fname)
|
||||
char *fname;
|
||||
{
|
||||
FILE *f;
|
||||
char line[2048];
|
||||
int rv = 0;
|
||||
gboolean startchar = FALSE, startbitmap = FALSE;
|
||||
char *charname,*p,*bitmap;
|
||||
int dx = 0,dy = 0;
|
||||
int w,h,x,y,py;
|
||||
int id,tmp;
|
||||
|
||||
dw = 0;
|
||||
dh = 0;
|
||||
|
||||
if (!(f = fopen(fname, "r")))
|
||||
{
|
||||
perror(fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fgets(line, sizeof(line), f) && strncasecmp("STARTFONT ", line, 10))
|
||||
{
|
||||
printf("!BDF font file\n");
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = line;
|
||||
while (fgets(line, sizeof(line), f))
|
||||
{
|
||||
if (!startchar)
|
||||
{
|
||||
if (!strncasecmp("STARTCHAR ", line, 10))
|
||||
{
|
||||
startchar = TRUE;
|
||||
charname = g_strndup(p + 10,
|
||||
strcspn(p+10, "\r\n"));
|
||||
}
|
||||
else if (!strncasecmp("FONTBOUNDINGBOX ", line, 16))
|
||||
sscanf(p+16, "%d %d %d %d", &dw, &dh, &dx, &dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strncasecmp("ENDCHAR", line, 7))
|
||||
{
|
||||
font_info_t *nfi;
|
||||
|
||||
if (debug)
|
||||
printf(" %*s*/\n", dw, "");
|
||||
startchar = FALSE;
|
||||
startbitmap = FALSE;
|
||||
|
||||
nfi = g_malloc(sizeof(font_info_t));
|
||||
memset(nfi, '\0', sizeof(font_info_t));
|
||||
|
||||
nfi->name = charname;
|
||||
nfi->id = id;
|
||||
nfi->bitmap = bitmap;
|
||||
nfi->hotx = 0 - dx;
|
||||
nfi->hoty = 0 - dy;
|
||||
|
||||
fonts = g_slist_append(fonts, nfi);
|
||||
}
|
||||
else if (startbitmap)
|
||||
{
|
||||
int px,cx;
|
||||
guchar mask;
|
||||
|
||||
px = x - dx + py * dw;
|
||||
for (cx = 0; cx < w; cx++)
|
||||
{
|
||||
mask = 1 << (3 - (cx % 4));
|
||||
|
||||
bitmap[px+cx] =
|
||||
(mask & HEX(line[cx/4])) != 0;
|
||||
|
||||
if (debug)
|
||||
printf(bitmap[px+cx] ? "X" : " ");
|
||||
}
|
||||
py++;
|
||||
if (debug)
|
||||
printf(" %*s*/\n/* %*s", dw-w, "", dw+dx, "");
|
||||
}
|
||||
else if (!strncasecmp("BBX ", line, 4))
|
||||
{
|
||||
sscanf(p+4, "%d %d %d %d", &w, &h, &x, &y);
|
||||
if (debug)
|
||||
printf("/* %s: */\n/* %*s", charname, dw+dx, "");
|
||||
}
|
||||
else if (!strncasecmp("ENCODING ", line, 9))
|
||||
{
|
||||
if (sscanf(p+9, "%d %d", &tmp, &id) != 2)
|
||||
id = tmp;
|
||||
}
|
||||
else if (!strncasecmp("BITMAP", line, 6))
|
||||
{
|
||||
py = y - dy;
|
||||
startbitmap = TRUE;
|
||||
bitmap = g_malloc(dw*dh);
|
||||
memset(bitmap, '\0', dw*dh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strncasecmp("ENDFONT", line, 7))
|
||||
rv = -1;
|
||||
|
||||
fclose(f);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int font_info_compare(fi, name)
|
||||
font_info_t *fi;
|
||||
char *name;
|
||||
{
|
||||
return strcmp(name, fi->name);
|
||||
}
|
||||
|
||||
static cursor_info_t *gen_cursor(bmap, mask)
|
||||
font_info_t *bmap;
|
||||
font_info_t *mask;
|
||||
{
|
||||
cursor_info_t *ci;
|
||||
int bx = dw,by = dh,ex = 0,ey = 0;
|
||||
int i,j;
|
||||
|
||||
for (j = 0; j < dh; j++)
|
||||
{
|
||||
gboolean havep = FALSE;
|
||||
|
||||
for (i = 0; i < dw; i++)
|
||||
{
|
||||
if (bmap->bitmap[j*dw+i] || mask->bitmap[j*dw+i])
|
||||
{
|
||||
havep = TRUE;
|
||||
bx = MIN(bx, i);
|
||||
ex = MAX(i+1, ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (havep)
|
||||
{
|
||||
by = MIN(by, j);
|
||||
ey = MAX(ey, j+1);
|
||||
}
|
||||
}
|
||||
|
||||
ci = g_malloc(sizeof(cursor_info_t));
|
||||
ci->name = g_strdup(bmap->name);
|
||||
ci->id = bmap->id;
|
||||
|
||||
ci->width = ex - bx;
|
||||
ci->height = ey - by;
|
||||
|
||||
ci->hotx = bmap->hotx - bx;
|
||||
ci->hoty = ci->height - (bmap->hoty - by);
|
||||
|
||||
ci->data = g_malloc(ci->width * ci->height);
|
||||
memset(ci->data, '\0', ci->width * ci->height);
|
||||
|
||||
for (j = 0; j < ci->height; j++)
|
||||
{
|
||||
for (i = 0; i < ci->width; i++)
|
||||
{
|
||||
int ofs = (by + j) * dw + bx + i;
|
||||
|
||||
ci->data[j*ci->width + i] = mask->bitmap[ofs] *
|
||||
(1 + bmap->bitmap[ofs]);
|
||||
}
|
||||
}
|
||||
|
||||
return ci;
|
||||
}
|
||||
|
||||
static void compose_cursors_from_fonts()
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = g_slist_copy (fonts); l; l = g_slist_delete_link (l,l))
|
||||
{
|
||||
font_info_t *fi = l->data;
|
||||
char *name;
|
||||
GSList *ml;
|
||||
|
||||
name = g_strconcat(fi->name, "_mask", NULL);
|
||||
|
||||
if ((ml = g_slist_find_custom(fonts, name,
|
||||
(GCompareFunc) font_info_compare)))
|
||||
{
|
||||
cursors = g_slist_append(cursors, gen_cursor(l->data, ml->data));
|
||||
fonts = g_slist_remove(fonts, l->data);
|
||||
fonts = g_slist_remove(fonts, ml->data);
|
||||
}
|
||||
|
||||
g_free(name);
|
||||
}
|
||||
}
|
||||
|
||||
static char *dump_cursor(ci, id)
|
||||
cursor_info_t *ci;
|
||||
int id;
|
||||
{
|
||||
static char cdata[8192];
|
||||
char *p;
|
||||
int i;
|
||||
int c;
|
||||
gboolean flushed;
|
||||
|
||||
sprintf(cdata, " { \"%s\", %d, %d, %d, %d, %d, \n \"",
|
||||
ci->name, ci->id, ci->width, ci->height, ci->hotx, ci->hoty);
|
||||
p = cdata + strlen(cdata);
|
||||
|
||||
for (i = 0; i < ci->width * ci->height; i++)
|
||||
{
|
||||
flushed = FALSE;
|
||||
|
||||
if (!(i%4))
|
||||
c = 0;
|
||||
|
||||
c = c << 2;
|
||||
|
||||
c += ci->data[i];
|
||||
|
||||
if ((i % 4) == 3)
|
||||
{
|
||||
flushed = TRUE;
|
||||
sprintf(p, "\\%03o", c);
|
||||
p += strlen(p);
|
||||
}
|
||||
|
||||
if (i > 0 && !(i % 64))
|
||||
{
|
||||
strcpy(p ,"\"\n \"");
|
||||
p += strlen(p);
|
||||
}
|
||||
}
|
||||
if (!flushed)
|
||||
{
|
||||
sprintf(p, "\\%03o", c);
|
||||
p += strlen(p);
|
||||
}
|
||||
|
||||
strcpy(p, "\" }");
|
||||
|
||||
return cdata;
|
||||
}
|
||||
|
||||
static int dump_cursors()
|
||||
{
|
||||
GSList *ptr;
|
||||
FILE *f = stdout;
|
||||
|
||||
fprintf(f, "static const struct { const char *name; int type; guchar width; guchar height; guchar hotx; guchar hoty; guchar *data; } cursors[] = {\n");
|
||||
|
||||
for (ptr = cursors; ptr; ptr = ptr->next)
|
||||
{
|
||||
if (debug)
|
||||
print_cursor(ptr->data);
|
||||
fprintf(f, "%s, \n", dump_cursor(ptr->data));
|
||||
}
|
||||
|
||||
fprintf(f, " { NULL, 0, 0, 0, 0, 0, NULL },\n};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("missing parameters !\n");
|
||||
printf("Usage: %s [BDF cursor file]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (g_getenv ("BDFCURSOR_DEBUG") != NULL)
|
||||
debug = TRUE;
|
||||
|
||||
if (read_bdf_font(argv[1]) || !fonts)
|
||||
{
|
||||
printf("Error reading font\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
compose_cursors_from_fonts();
|
||||
|
||||
if (!cursors)
|
||||
{
|
||||
printf("failed to generate cursors from font!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dump_cursors();
|
||||
|
||||
if (fonts)
|
||||
{
|
||||
printf("some fonts remained unconverted!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -945,71 +945,38 @@ _gdk_win32_enable_hidpi (GdkWin32Display *display)
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type)
|
||||
static void
|
||||
_gdk_win32_check_on_arm64 (GdkWin32Display *display)
|
||||
{
|
||||
static gsize checked = 0;
|
||||
static gboolean is_arm64 = FALSE;
|
||||
static gboolean is_wow64 = FALSE;
|
||||
|
||||
if (g_once_init_enter (&checked))
|
||||
{
|
||||
gboolean fallback_wow64_check = FALSE;
|
||||
HMODULE kernel32 = LoadLibraryW (L"kernel32.dll");
|
||||
|
||||
if (kernel32 != NULL)
|
||||
{
|
||||
typedef BOOL (WINAPI *funcIsWow64Process2) (HANDLE, USHORT *, USHORT *);
|
||||
|
||||
funcIsWow64Process2 isWow64Process2 =
|
||||
display->cpu_funcs.isWow64Process2 =
|
||||
(funcIsWow64Process2) GetProcAddress (kernel32, "IsWow64Process2");
|
||||
|
||||
if (isWow64Process2 != NULL)
|
||||
if (display->cpu_funcs.isWow64Process2 != NULL)
|
||||
{
|
||||
USHORT proc_cpu = 0;
|
||||
USHORT native_cpu = 0;
|
||||
|
||||
isWow64Process2 (GetCurrentProcess (), &proc_cpu, &native_cpu);
|
||||
display->cpu_funcs.isWow64Process2 (GetCurrentProcess (),
|
||||
&proc_cpu,
|
||||
&native_cpu);
|
||||
|
||||
if (native_cpu == IMAGE_FILE_MACHINE_ARM64)
|
||||
is_arm64 = TRUE;
|
||||
|
||||
if (proc_cpu != IMAGE_FILE_MACHINE_UNKNOWN)
|
||||
is_wow64 = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fallback_wow64_check = TRUE;
|
||||
display->running_on_arm64 = TRUE;
|
||||
}
|
||||
|
||||
FreeLibrary (kernel32);
|
||||
}
|
||||
else
|
||||
{
|
||||
fallback_wow64_check = TRUE;
|
||||
}
|
||||
|
||||
if (fallback_wow64_check)
|
||||
IsWow64Process (GetCurrentProcess (), &is_wow64);
|
||||
|
||||
g_once_init_leave (&checked, 1);
|
||||
}
|
||||
|
||||
switch (check_type)
|
||||
{
|
||||
case GDK_WIN32_ARM64:
|
||||
return is_arm64;
|
||||
break;
|
||||
|
||||
case GDK_WIN32_WOW64:
|
||||
return is_wow64;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("unknown CPU check type");
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1020,7 +987,7 @@ gdk_win32_display_init (GdkWin32Display *display_win32)
|
||||
display_win32->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR));
|
||||
|
||||
_gdk_win32_enable_hidpi (display_win32);
|
||||
display_win32->running_on_arm64 = _gdk_win32_check_processor (GDK_WIN32_ARM64);
|
||||
_gdk_win32_check_on_arm64 (display_win32);
|
||||
|
||||
/* if we have DPI awareness, set up fixed scale if set */
|
||||
if (display_win32->dpi_aware_type != PROCESS_DPI_UNAWARE &&
|
||||
@@ -1175,18 +1142,16 @@ gdk_win32_display_get_setting (GdkDisplay *display,
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#endif
|
||||
|
||||
static GdkGLContext *
|
||||
gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
static gboolean
|
||||
gdk_win32_display_init_gl_backend (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
HDC init_gl_hdc = NULL;
|
||||
|
||||
if (display_win32->dummy_context_wgl.hdc == NULL)
|
||||
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
||||
|
||||
init_gl_hdc = display_win32->dummy_context_wgl.hdc;
|
||||
|
||||
/*
|
||||
* No env vars set, do the regular GL initialization, first WGL and then EGL,
|
||||
* as WGL is the more tried-and-tested configuration.
|
||||
@@ -1194,50 +1159,59 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
/*
|
||||
* Disable defaulting to EGL as EGL is used more as a compatibility layer
|
||||
* Disable defaulting to EGL for now, since shaders need to be fixed for
|
||||
* usage against libANGLE EGL. EGL is used more as a compatibility layer
|
||||
* on Windows rather than being a native citizen on Windows
|
||||
*/
|
||||
if (GDK_DEBUG_CHECK (GL_EGL) || GDK_DEBUG_CHECK (GL_GLES))
|
||||
{
|
||||
if (gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_ANGLE_ANGLE,
|
||||
init_gl_hdc,
|
||||
FALSE,
|
||||
error))
|
||||
{
|
||||
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
g_clear_error (error);
|
||||
}
|
||||
if (_gdk_debug_flags & GDK_DEBUG_GL_EGL)
|
||||
result = gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_ANGLE_ANGLE,
|
||||
display_win32->dummy_context_wgl.hdc,
|
||||
FALSE,
|
||||
error);
|
||||
#endif
|
||||
|
||||
if (gdk_win32_display_init_wgl (display, error))
|
||||
if (!result)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
|
||||
"display", display,
|
||||
NULL);
|
||||
g_clear_error (error);
|
||||
result = gdk_win32_display_init_wgl (display, error);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
g_clear_error (error);
|
||||
|
||||
if (gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_ANGLE_ANGLE,
|
||||
init_gl_hdc,
|
||||
TRUE,
|
||||
error))
|
||||
if (!result)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
g_clear_error (error);
|
||||
result = gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_ANGLE_ANGLE,
|
||||
display_win32->dummy_context_wgl.hdc,
|
||||
TRUE,
|
||||
error);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
static GdkGLContext *
|
||||
gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkGLContext *gl_context = NULL;
|
||||
|
||||
if (!gdk_win32_display_init_gl_backend (display, error))
|
||||
return NULL;
|
||||
|
||||
if (display_win32->wgl_pixel_format != 0)
|
||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, "display", display, NULL);
|
||||
#ifdef HAVE_EGL
|
||||
else if (gdk_display_get_egl_display (display))
|
||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail (gl_context != NULL, NULL);
|
||||
|
||||
return gl_context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -105,6 +105,13 @@ typedef enum {
|
||||
GDK_WIN32_TABLET_INPUT_API_WINPOINTER
|
||||
} GdkWin32TabletInputAPI;
|
||||
|
||||
/* Detect running architecture */
|
||||
typedef BOOL (WINAPI *funcIsWow64Process2) (HANDLE, USHORT *, USHORT *);
|
||||
typedef struct _GdkWin32KernelCPUFuncs
|
||||
{
|
||||
funcIsWow64Process2 isWow64Process2;
|
||||
} GdkWin32KernelCPUFuncs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HDC hdc;
|
||||
@@ -125,6 +132,7 @@ struct _GdkWin32Display
|
||||
|
||||
/* WGL/OpenGL Items */
|
||||
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
||||
int wgl_pixel_format;
|
||||
guint gl_version;
|
||||
|
||||
GListModel *monitors;
|
||||
@@ -169,6 +177,7 @@ struct _GdkWin32Display
|
||||
|
||||
/* Running CPU items */
|
||||
guint running_on_arm64 : 1;
|
||||
GdkWin32KernelCPUFuncs cpu_funcs;
|
||||
};
|
||||
|
||||
struct _GdkWin32DisplayClass
|
||||
|
||||
+314
-306
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2020. See the AUTHORS
|
||||
* 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/.
|
||||
@@ -157,6 +157,7 @@ static HKL latin_locale = NULL;
|
||||
|
||||
static gboolean in_ime_composition = FALSE;
|
||||
static UINT modal_timer;
|
||||
static UINT sync_timer = 0;
|
||||
|
||||
static int debug_indent = 0;
|
||||
|
||||
@@ -644,9 +645,11 @@ build_key_event_state (BYTE *key_state)
|
||||
{
|
||||
GdkModifierType state;
|
||||
GdkWin32Keymap *keymap;
|
||||
keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display));
|
||||
|
||||
state = _gdk_win32_keymap_get_mod_mask (keymap);
|
||||
state = 0;
|
||||
|
||||
if (key_state[VK_SHIFT] & 0x80)
|
||||
state |= GDK_SHIFT_MASK;
|
||||
|
||||
if (key_state[VK_CAPITAL] & 0x01)
|
||||
state |= GDK_LOCK_MASK;
|
||||
@@ -662,6 +665,26 @@ build_key_event_state (BYTE *key_state)
|
||||
if (key_state[VK_XBUTTON2] & 0x80)
|
||||
state |= GDK_BUTTON5_MASK;
|
||||
|
||||
keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display));
|
||||
|
||||
if (_gdk_win32_keymap_has_altgr (keymap) &&
|
||||
(key_state[VK_LCONTROL] & 0x80) &&
|
||||
(key_state[VK_RMENU] & 0x80))
|
||||
{
|
||||
state |= GDK_MOD2_MASK;
|
||||
if (key_state[VK_RCONTROL] & 0x80)
|
||||
state |= GDK_CONTROL_MASK;
|
||||
if (key_state[VK_LMENU] & 0x80)
|
||||
state |= GDK_ALT_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key_state[VK_CONTROL] & 0x80)
|
||||
state |= GDK_CONTROL_MASK;
|
||||
if (key_state[VK_MENU] & 0x80)
|
||||
state |= GDK_ALT_MASK;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1430,6 +1453,23 @@ _gdk_win32_end_modal_call (GdkWin32ModalOpKind kind)
|
||||
}
|
||||
}
|
||||
|
||||
static VOID CALLBACK
|
||||
sync_timer_proc (HWND hwnd,
|
||||
UINT msg,
|
||||
UINT_PTR id,
|
||||
DWORD time)
|
||||
{
|
||||
MSG message;
|
||||
if (PeekMessageW (&message, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RedrawWindow (hwnd, NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ALLCHILDREN);
|
||||
|
||||
KillTimer (hwnd, sync_timer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_nchittest (HWND hwnd,
|
||||
GdkSurface *window,
|
||||
@@ -1740,12 +1780,16 @@ gdk_event_translate (MSG *msg,
|
||||
POINT point;
|
||||
MINMAXINFO *mmi;
|
||||
HWND hwnd;
|
||||
BYTE key_state[256];
|
||||
HIMC himc;
|
||||
WINDOWPOS *windowpos;
|
||||
gboolean ignore_leave;
|
||||
|
||||
GdkEvent *event;
|
||||
|
||||
wchar_t wbuf[100];
|
||||
int ccount;
|
||||
|
||||
GdkDisplay *display;
|
||||
GdkSurface *window = NULL;
|
||||
GdkWin32Surface *impl;
|
||||
@@ -1763,12 +1807,20 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
int button;
|
||||
|
||||
char buf[256];
|
||||
gboolean return_val = FALSE;
|
||||
|
||||
int i;
|
||||
|
||||
GdkModifierType state;
|
||||
guint keyval;
|
||||
guint16 keycode;
|
||||
guint8 group;
|
||||
gboolean is_modifier;
|
||||
|
||||
double delta_x, delta_y;
|
||||
GdkScrollDirection direction;
|
||||
GdkTranslatedKey translated;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
win32_display = GDK_WIN32_DISPLAY (display);
|
||||
@@ -1827,39 +1879,35 @@ gdk_event_translate (MSG *msg,
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_INPUTLANGCHANGE:
|
||||
{
|
||||
GdkWin32Keymap *win32_keymap;
|
||||
GdkTranslatedKey translated;
|
||||
_gdk_input_locale = (HKL) msg->lParam;
|
||||
_gdk_win32_keymap_set_active_layout (GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display)), _gdk_input_locale);
|
||||
GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
|
||||
LOCALE_IDEFAULTANSICODEPAGE,
|
||||
buf, sizeof (buf));
|
||||
_gdk_input_codepage = atoi (buf);
|
||||
_gdk_keymap_serial++;
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print (" cs:%lu hkl:%p%s cp:%d",
|
||||
(gulong) msg->wParam,
|
||||
(gpointer) msg->lParam, _gdk_input_locale_is_ime ? " (IME)" : "",
|
||||
_gdk_input_codepage));
|
||||
gdk_display_setting_changed (display, "gtk-im-module");
|
||||
|
||||
win32_keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display));
|
||||
|
||||
_gdk_input_locale = (HKL) msg->lParam;
|
||||
_gdk_win32_keymap_set_active_layout (win32_keymap, _gdk_input_locale);
|
||||
_gdk_keymap_serial++;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print (" cs:%lu hkl:%p%s",
|
||||
(gulong) msg->wParam,
|
||||
(gpointer) msg->lParam,
|
||||
_gdk_input_locale_is_ime ? " (IME)" : ""));
|
||||
gdk_display_setting_changed (display, "gtk-im-module");
|
||||
|
||||
/* Generate a dummy key event to "nudge" IMContext */
|
||||
translated.keyval = GDK_KEY_VoidSymbol;
|
||||
translated.consumed = 0;
|
||||
translated.layout = 0;
|
||||
translated.level = 0;
|
||||
event = gdk_key_event_new (GDK_KEY_PRESS,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
0,
|
||||
0,
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated);
|
||||
_gdk_win32_append_event (event);
|
||||
}
|
||||
/* Generate a dummy key event to "nudge" IMContext */
|
||||
translated.keyval = GDK_KEY_VoidSymbol;
|
||||
translated.consumed = 0;
|
||||
translated.layout = 0;
|
||||
translated.level = 0;
|
||||
event = gdk_key_event_new (GDK_KEY_PRESS,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
0,
|
||||
0,
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated);
|
||||
_gdk_win32_append_event (event);
|
||||
break;
|
||||
|
||||
case WM_SYSKEYUP:
|
||||
@@ -1896,203 +1944,177 @@ gdk_event_translate (MSG *msg,
|
||||
decode_key_lparam (msg->lParam)));
|
||||
|
||||
keyup_or_down:
|
||||
{
|
||||
GdkWin32Keymap *win32_keymap;
|
||||
GdkModifierType state;
|
||||
guint keyval;
|
||||
guint16 keycode;
|
||||
guint8 group;
|
||||
gboolean is_modifier;
|
||||
GdkTranslatedKey translated;
|
||||
GdkTranslatedKey no_lock;
|
||||
BYTE key_state[256];
|
||||
wchar_t wbuf[100];
|
||||
int ccount = 0;
|
||||
|
||||
/* Ignore key messages intended for the IME */
|
||||
if (msg->wParam == VK_PROCESSKEY || in_ime_composition)
|
||||
break;
|
||||
/* Ignore key messages intended for the IME */
|
||||
if (msg->wParam == VK_PROCESSKEY ||
|
||||
in_ime_composition)
|
||||
break;
|
||||
|
||||
/* Ignore autorepeats on modifiers */
|
||||
if (msg->message == WM_KEYDOWN &&
|
||||
(msg->wParam == VK_MENU ||
|
||||
msg->wParam == VK_CONTROL ||
|
||||
msg->wParam == VK_SHIFT) &&
|
||||
((HIWORD(msg->lParam) & KF_REPEAT) >= 1))
|
||||
break;
|
||||
/* Ignore autorepeats on modifiers */
|
||||
if (msg->message == WM_KEYDOWN &&
|
||||
(msg->wParam == VK_MENU ||
|
||||
msg->wParam == VK_CONTROL ||
|
||||
msg->wParam == VK_SHIFT) &&
|
||||
((HIWORD(msg->lParam) & KF_REPEAT) >= 1))
|
||||
break;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
break;
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
break;
|
||||
|
||||
win32_keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (display));
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
API_CALL (GetKeyboardState, (key_state));
|
||||
API_CALL (GetKeyboardState, (key_state));
|
||||
|
||||
ccount = 0;
|
||||
ccount = 0;
|
||||
|
||||
if (msg->wParam == VK_PACKET)
|
||||
{
|
||||
ccount = ToUnicode (VK_PACKET, HIWORD (msg->lParam), key_state, wbuf, 1, 0);
|
||||
if (ccount == 1)
|
||||
{
|
||||
if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
|
||||
{
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
impl->leading_surrogate_keydown = wbuf[0];
|
||||
else
|
||||
impl->leading_surrogate_keyup = wbuf[0];
|
||||
if (msg->wParam == VK_PACKET)
|
||||
{
|
||||
ccount = ToUnicode (VK_PACKET, HIWORD (msg->lParam), key_state, wbuf, 1, 0);
|
||||
if (ccount == 1)
|
||||
{
|
||||
if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
|
||||
{
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
impl->leading_surrogate_keydown = wbuf[0];
|
||||
else
|
||||
impl->leading_surrogate_keyup = wbuf[0];
|
||||
|
||||
/* don't emit an event */
|
||||
return_val = TRUE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wait until an event is created */;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* don't emit an event */
|
||||
return_val = TRUE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wait until an event is created */;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keyval = GDK_KEY_VoidSymbol;
|
||||
keycode = msg->wParam;
|
||||
keyval = GDK_KEY_VoidSymbol;
|
||||
keycode = msg->wParam;
|
||||
|
||||
if (HIWORD (msg->lParam) & KF_EXTENDED)
|
||||
{
|
||||
switch (msg->wParam)
|
||||
{
|
||||
case VK_CONTROL:
|
||||
keycode = VK_RCONTROL;
|
||||
break;
|
||||
case VK_SHIFT: /* Actually, KF_EXTENDED is not set
|
||||
* for the right shift key.
|
||||
*/
|
||||
keycode = VK_RSHIFT;
|
||||
break;
|
||||
case VK_MENU:
|
||||
keycode = VK_RMENU;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (msg->wParam == VK_SHIFT &&
|
||||
LOBYTE (HIWORD (msg->lParam)) == _gdk_win32_keymap_get_rshift_scancode (win32_keymap))
|
||||
keycode = VK_RSHIFT;
|
||||
if (HIWORD (msg->lParam) & KF_EXTENDED)
|
||||
{
|
||||
switch (msg->wParam)
|
||||
{
|
||||
case VK_CONTROL:
|
||||
keycode = VK_RCONTROL;
|
||||
break;
|
||||
case VK_SHIFT: /* Actually, KF_EXTENDED is not set
|
||||
* for the right shift key.
|
||||
*/
|
||||
keycode = VK_RSHIFT;
|
||||
break;
|
||||
case VK_MENU:
|
||||
keycode = VK_RMENU;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (msg->wParam == VK_SHIFT &&
|
||||
LOBYTE (HIWORD (msg->lParam)) == _gdk_win32_keymap_get_rshift_scancode (GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display))))
|
||||
keycode = VK_RSHIFT;
|
||||
|
||||
is_modifier = (msg->wParam == VK_CONTROL ||
|
||||
msg->wParam == VK_SHIFT ||
|
||||
msg->wParam == VK_MENU);
|
||||
is_modifier = (msg->wParam == VK_CONTROL ||
|
||||
msg->wParam == VK_SHIFT ||
|
||||
msg->wParam == VK_MENU);
|
||||
/* g_print ("ctrl:%02x lctrl:%02x rctrl:%02x alt:%02x lalt:%02x ralt:%02x\n", key_state[VK_CONTROL], key_state[VK_LCONTROL], key_state[VK_RCONTROL], key_state[VK_MENU], key_state[VK_LMENU], key_state[VK_RMENU]); */
|
||||
|
||||
state = build_key_event_state (key_state);
|
||||
group = get_active_group ();
|
||||
state = build_key_event_state (key_state);
|
||||
group = get_active_group ();
|
||||
|
||||
if (msg->wParam == VK_PACKET && ccount == 1)
|
||||
{
|
||||
if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
else if (wbuf[0] >= 0xDC00 && wbuf[0] < 0xE000)
|
||||
{
|
||||
wchar_t leading;
|
||||
if (msg->wParam == VK_PACKET && ccount == 1)
|
||||
{
|
||||
if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
else if (wbuf[0] >= 0xDC00 && wbuf[0] < 0xE000)
|
||||
{
|
||||
wchar_t leading;
|
||||
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
leading = impl->leading_surrogate_keydown;
|
||||
else
|
||||
leading = impl->leading_surrogate_keyup;
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
leading = impl->leading_surrogate_keydown;
|
||||
else
|
||||
leading = impl->leading_surrogate_keyup;
|
||||
|
||||
keyval = gdk_unicode_to_keyval ((leading - 0xD800) * 0x400 + wbuf[0] - 0xDC00 + 0x10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyval = gdk_unicode_to_keyval (wbuf[0]);
|
||||
}
|
||||
keyval = gdk_unicode_to_keyval ((leading - 0xD800) * 0x400 + wbuf[0] - 0xDC00 + 0x10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyval = gdk_unicode_to_keyval (wbuf[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_keymap_translate_keyboard_state (_gdk_win32_display_get_keymap (display),
|
||||
keycode,
|
||||
state,
|
||||
group,
|
||||
&keyval,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
translated.keyval = keyval;
|
||||
translated.consumed = 0;
|
||||
translated.layout = 0;
|
||||
translated.level = 0;
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
impl->leading_surrogate_keydown = 0;
|
||||
else
|
||||
impl->leading_surrogate_keyup = 0;
|
||||
|
||||
no_lock = translated;
|
||||
}
|
||||
else
|
||||
{
|
||||
int level = 0;
|
||||
int effective_group = 0;
|
||||
GdkModifierType consumed = 0;
|
||||
/* Only one release key event is fired when both shift keys are pressed together
|
||||
and then released. In order to send the missing event, press events for shift
|
||||
keys are recorded and sent together when the release event occurs.
|
||||
Other modifiers (e.g. ctrl, alt) don't have this problem. */
|
||||
if (msg->message == WM_KEYDOWN && msg->wParam == VK_SHIFT)
|
||||
{
|
||||
int pressed_shift = msg->lParam & 0xffffff; /* mask shift modifier */
|
||||
if (both_shift_pressed[0] == 0)
|
||||
both_shift_pressed[0] = pressed_shift;
|
||||
else if (both_shift_pressed[0] != pressed_shift)
|
||||
both_shift_pressed[1] = pressed_shift;
|
||||
}
|
||||
|
||||
gdk_keymap_translate_keyboard_state ((GdkKeymap*) win32_keymap, keycode, state, group,
|
||||
&keyval, &effective_group, &level, &consumed);
|
||||
translated.keyval = keyval;
|
||||
translated.consumed = consumed;
|
||||
translated.layout = effective_group;
|
||||
translated.level = level;
|
||||
if (msg->message == WM_KEYUP && msg->wParam == VK_SHIFT)
|
||||
{
|
||||
if (both_shift_pressed[0] != 0 && both_shift_pressed[1] != 0)
|
||||
{
|
||||
int tmp_retval;
|
||||
MSG fake_release = *msg;
|
||||
int pressed_shift = msg->lParam & 0xffffff;
|
||||
|
||||
gdk_keymap_translate_keyboard_state ((GdkKeymap*) win32_keymap, keycode,
|
||||
state & ~GDK_LOCK_MASK, group, &keyval,
|
||||
&effective_group, &level, &consumed);
|
||||
no_lock.keyval = keyval;
|
||||
no_lock.consumed = consumed;
|
||||
no_lock.layout = effective_group;
|
||||
no_lock.level = level;
|
||||
}
|
||||
if (both_shift_pressed[0] == pressed_shift)
|
||||
fake_release.lParam = both_shift_pressed[1];
|
||||
else
|
||||
fake_release.lParam = both_shift_pressed[0];
|
||||
|
||||
if (msg->message == WM_KEYDOWN)
|
||||
impl->leading_surrogate_keydown = 0;
|
||||
else
|
||||
impl->leading_surrogate_keyup = 0;
|
||||
both_shift_pressed[0] = both_shift_pressed[1] = 0;
|
||||
gdk_event_translate (&fake_release, &tmp_retval);
|
||||
}
|
||||
both_shift_pressed[0] = both_shift_pressed[1] = 0;
|
||||
}
|
||||
|
||||
/* Only one release key event is fired when both shift keys are pressed together
|
||||
and then released. In order to send the missing event, press events for shift
|
||||
keys are recorded and sent together when the release event occurs.
|
||||
Other modifiers (e.g. ctrl, alt) don't have this problem. */
|
||||
if (msg->message == WM_KEYDOWN && msg->wParam == VK_SHIFT)
|
||||
{
|
||||
int pressed_shift = msg->lParam & 0xffffff; /* mask shift modifier */
|
||||
if (both_shift_pressed[0] == 0)
|
||||
both_shift_pressed[0] = pressed_shift;
|
||||
else if (both_shift_pressed[0] != pressed_shift)
|
||||
both_shift_pressed[1] = pressed_shift;
|
||||
}
|
||||
/* Reset ALT_MASK if it is the Alt key itself */
|
||||
if (msg->wParam == VK_MENU)
|
||||
state &= ~GDK_ALT_MASK;
|
||||
|
||||
if (msg->message == WM_KEYUP && msg->wParam == VK_SHIFT)
|
||||
{
|
||||
if (both_shift_pressed[0] != 0 && both_shift_pressed[1] != 0)
|
||||
{
|
||||
int tmp_retval;
|
||||
MSG fake_release = *msg;
|
||||
int pressed_shift = msg->lParam & 0xffffff;
|
||||
/* FIXME do proper translation */
|
||||
translated.keyval = keyval;
|
||||
translated.consumed = 0;
|
||||
translated.layout = group;
|
||||
translated.level = 0;
|
||||
event = gdk_key_event_new ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
|
||||
? GDK_KEY_PRESS
|
||||
: GDK_KEY_RELEASE,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
keycode,
|
||||
state,
|
||||
is_modifier,
|
||||
&translated,
|
||||
&translated);
|
||||
|
||||
if (both_shift_pressed[0] == pressed_shift)
|
||||
fake_release.lParam = both_shift_pressed[1];
|
||||
else
|
||||
fake_release.lParam = both_shift_pressed[0];
|
||||
_gdk_win32_append_event (event);
|
||||
|
||||
both_shift_pressed[0] = both_shift_pressed[1] = 0;
|
||||
gdk_event_translate (&fake_release, &tmp_retval);
|
||||
}
|
||||
both_shift_pressed[0] = both_shift_pressed[1] = 0;
|
||||
}
|
||||
|
||||
/* Reset ALT_MASK if it is the Alt key itself */
|
||||
if (msg->wParam == VK_MENU)
|
||||
state &= ~GDK_ALT_MASK;
|
||||
|
||||
event = gdk_key_event_new ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
|
||||
? GDK_KEY_PRESS
|
||||
: GDK_KEY_RELEASE,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
keycode,
|
||||
state,
|
||||
is_modifier,
|
||||
&translated,
|
||||
&no_lock);
|
||||
|
||||
_gdk_win32_append_event (event);
|
||||
|
||||
return_val = TRUE;
|
||||
}
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_SYSCHAR:
|
||||
@@ -2113,82 +2135,73 @@ gdk_event_translate (MSG *msg,
|
||||
break;
|
||||
|
||||
case WM_IME_COMPOSITION:
|
||||
{
|
||||
BYTE key_state[256];
|
||||
wchar_t wbuf[100];
|
||||
int ccount = 0;
|
||||
/* On Win2k WM_IME_CHAR doesn't work correctly for non-Unicode
|
||||
* applications. Thus, handle WM_IME_COMPOSITION with
|
||||
* GCS_RESULTSTR instead, fetch the Unicode chars from the IME
|
||||
* with ImmGetCompositionStringW().
|
||||
*
|
||||
* See for instance
|
||||
* http://groups.google.com/groups?selm=natX5.57%24g77.19788%40nntp2.onemain.com
|
||||
* and
|
||||
* http://groups.google.com/groups?selm=u2XfrXw5BHA.1628%40tkmsftngp02
|
||||
* for comments by other people that seems to have the same
|
||||
* experience. WM_IME_CHAR just gives question marks, apparently
|
||||
* because of going through some conversion to the current code
|
||||
* page.
|
||||
*
|
||||
* WM_IME_CHAR might work on NT4 or Win9x with ActiveIMM, but
|
||||
* use WM_IME_COMPOSITION there, too, to simplify the code.
|
||||
*/
|
||||
GDK_NOTE (EVENTS, g_print (" %#lx", (long) msg->lParam));
|
||||
|
||||
/* On Win2k WM_IME_CHAR doesn't work correctly for non-Unicode
|
||||
* applications. Thus, handle WM_IME_COMPOSITION with
|
||||
* GCS_RESULTSTR instead, fetch the Unicode chars from the IME
|
||||
* with ImmGetCompositionStringW().
|
||||
*
|
||||
* See for instance
|
||||
* http://groups.google.com/groups?selm=natX5.57%24g77.19788%40nntp2.onemain.com
|
||||
* and
|
||||
* http://groups.google.com/groups?selm=u2XfrXw5BHA.1628%40tkmsftngp02
|
||||
* for comments by other people that seems to have the same
|
||||
* experience. WM_IME_CHAR just gives question marks, apparently
|
||||
* because of going through some conversion to the current code
|
||||
* page.
|
||||
*
|
||||
* WM_IME_CHAR might work on NT4 or Win9x with ActiveIMM, but
|
||||
* use WM_IME_COMPOSITION there, too, to simplify the code.
|
||||
*/
|
||||
GDK_NOTE (EVENTS, g_print (" %#lx", (long) msg->lParam));
|
||||
if (!(msg->lParam & GCS_RESULTSTR))
|
||||
break;
|
||||
|
||||
if (!(msg->lParam & GCS_RESULTSTR))
|
||||
break;
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
break;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
break;
|
||||
himc = ImmGetContext (msg->hwnd);
|
||||
ccount = ImmGetCompositionStringW (himc, GCS_RESULTSTR,
|
||||
wbuf, sizeof (wbuf));
|
||||
ImmReleaseContext (msg->hwnd, himc);
|
||||
|
||||
himc = ImmGetContext (msg->hwnd);
|
||||
ccount = ImmGetCompositionStringW (himc, GCS_RESULTSTR,
|
||||
wbuf, sizeof (wbuf));
|
||||
ImmReleaseContext (msg->hwnd, himc);
|
||||
ccount /= 2;
|
||||
|
||||
ccount /= 2;
|
||||
API_CALL (GetKeyboardState, (key_state));
|
||||
|
||||
API_CALL (GetKeyboardState, (key_state));
|
||||
for (i = 0; i < ccount; i++)
|
||||
{
|
||||
/* Build a key press event */
|
||||
translated.keyval = gdk_unicode_to_keyval (wbuf[i]);
|
||||
translated.consumed = 0;
|
||||
translated.layout = get_active_group ();
|
||||
translated.level = 0;
|
||||
event = gdk_key_event_new (GDK_KEY_PRESS,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
0,
|
||||
build_key_event_state (key_state),
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated);
|
||||
|
||||
for (i = 0; i < ccount; i++)
|
||||
{
|
||||
GdkTranslatedKey translated;
|
||||
_gdk_win32_append_event (event);
|
||||
|
||||
/* Build a key press event */
|
||||
translated.keyval = gdk_unicode_to_keyval (wbuf[i]);
|
||||
translated.consumed = 0;
|
||||
translated.layout = get_active_group ();
|
||||
translated.level = 0;
|
||||
event = gdk_key_event_new (GDK_KEY_PRESS,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
0,
|
||||
build_key_event_state (key_state),
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated);
|
||||
/* Build a key release event. */
|
||||
event = gdk_key_event_new (GDK_KEY_RELEASE,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
0,
|
||||
build_key_event_state (key_state),
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated);
|
||||
|
||||
_gdk_win32_append_event (event);
|
||||
|
||||
/* Build a key release event. */
|
||||
event = gdk_key_event_new (GDK_KEY_RELEASE,
|
||||
window,
|
||||
device_manager_win32->core_keyboard,
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
0,
|
||||
build_key_event_state (key_state),
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated);
|
||||
|
||||
_gdk_win32_append_event (event);
|
||||
}
|
||||
|
||||
return_val = TRUE;
|
||||
}
|
||||
_gdk_win32_append_event (event);
|
||||
}
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
@@ -2841,6 +2854,12 @@ gdk_event_translate (MSG *msg,
|
||||
*ret_valp = 1;
|
||||
break;
|
||||
|
||||
case WM_SYNCPAINT:
|
||||
sync_timer = SetTimer (GDK_SURFACE_HWND (window),
|
||||
1,
|
||||
200, sync_timer_proc);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
handle_wm_paint (msg, window);
|
||||
break;
|
||||
@@ -2985,22 +3004,17 @@ gdk_event_translate (MSG *msg,
|
||||
break;
|
||||
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
char buf[256];
|
||||
GDK_NOTE (EVENTS, (windowpos = (WINDOWPOS *) msg->lParam,
|
||||
g_print (" %s %s %dx%d@%+d%+d now below %p",
|
||||
_gdk_win32_surface_pos_bits_to_string (windowpos->flags),
|
||||
(windowpos->hwndInsertAfter == HWND_BOTTOM ? "BOTTOM" :
|
||||
(windowpos->hwndInsertAfter == HWND_NOTOPMOST ? "NOTOPMOST" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOP ? "TOP" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOPMOST ? "TOPMOST" :
|
||||
(sprintf (buf, "%p", windowpos->hwndInsertAfter),
|
||||
buf))))),
|
||||
windowpos->cx, windowpos->cy, windowpos->x, windowpos->y,
|
||||
GetNextWindow (msg->hwnd, GW_HWNDPREV))));
|
||||
}
|
||||
#endif
|
||||
GDK_NOTE (EVENTS, (windowpos = (WINDOWPOS *) msg->lParam,
|
||||
g_print (" %s %s %dx%d@%+d%+d now below %p",
|
||||
_gdk_win32_surface_pos_bits_to_string (windowpos->flags),
|
||||
(windowpos->hwndInsertAfter == HWND_BOTTOM ? "BOTTOM" :
|
||||
(windowpos->hwndInsertAfter == HWND_NOTOPMOST ? "NOTOPMOST" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOP ? "TOP" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOPMOST ? "TOPMOST" :
|
||||
(sprintf (buf, "%p", windowpos->hwndInsertAfter),
|
||||
buf))))),
|
||||
windowpos->cx, windowpos->cy, windowpos->x, windowpos->y,
|
||||
GetNextWindow (msg->hwnd, GW_HWNDPREV))));
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
{
|
||||
@@ -3026,21 +3040,15 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
windowpos = (WINDOWPOS *) msg->lParam;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
char buf[256];
|
||||
GDK_NOTE (EVENTS, g_print (" %s %s %dx%d@%+d%+d",
|
||||
_gdk_win32_surface_pos_bits_to_string (windowpos->flags),
|
||||
(windowpos->hwndInsertAfter == HWND_BOTTOM ? "BOTTOM" :
|
||||
(windowpos->hwndInsertAfter == HWND_NOTOPMOST ? "NOTOPMOST" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOP ? "TOP" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOPMOST ? "TOPMOST" :
|
||||
(sprintf (buf, "%p", windowpos->hwndInsertAfter),
|
||||
buf))))),
|
||||
windowpos->cx, windowpos->cy, windowpos->x, windowpos->y));
|
||||
}
|
||||
#endif
|
||||
GDK_NOTE (EVENTS, g_print (" %s %s %dx%d@%+d%+d",
|
||||
_gdk_win32_surface_pos_bits_to_string (windowpos->flags),
|
||||
(windowpos->hwndInsertAfter == HWND_BOTTOM ? "BOTTOM" :
|
||||
(windowpos->hwndInsertAfter == HWND_NOTOPMOST ? "NOTOPMOST" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOP ? "TOP" :
|
||||
(windowpos->hwndInsertAfter == HWND_TOPMOST ? "TOPMOST" :
|
||||
(sprintf (buf, "%p", windowpos->hwndInsertAfter),
|
||||
buf))))),
|
||||
windowpos->cx, windowpos->cy, windowpos->x, windowpos->y));
|
||||
|
||||
/* Break grabs on unmap or minimize */
|
||||
if (windowpos->flags & SWP_HIDEWINDOW ||
|
||||
|
||||
@@ -258,6 +258,9 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
|
||||
return FALSE;
|
||||
|
||||
if (display_win32->wgl_pixel_format != 0)
|
||||
return TRUE;
|
||||
|
||||
/* acquire and cache dummy Window (HWND & HDC) and
|
||||
* dummy GL Context, it is used to query functions
|
||||
* and used for other stuff as well
|
||||
@@ -296,6 +299,8 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
display_win32->wgl_pixel_format = best_idx;
|
||||
|
||||
display_win32->hasWglARBCreateContext =
|
||||
epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context");
|
||||
display_win32->hasWglEXTSwapControl =
|
||||
@@ -427,13 +432,33 @@ create_wgl_context (HDC hdc,
|
||||
goto gl_fail;
|
||||
}
|
||||
|
||||
hglrc = create_wgl_context_with_attribs (hdc,
|
||||
hglrc_base,
|
||||
share,
|
||||
flags,
|
||||
major,
|
||||
minor,
|
||||
is_legacy);
|
||||
/*
|
||||
* We need a Core GL 4.1 context in order to use the GL support in
|
||||
* the GStreamer media widget backend, but wglCreateContextAttribsARB()
|
||||
* may only give us the GL context version that we ask for here, and
|
||||
* nothing more. So, if we are asking for a pre-GL 4.1 context,
|
||||
* try to ask for a 4.1 context explicitly first. If that is not supported,
|
||||
* then we fall back to whatever version that we were asking for (or, even a
|
||||
* legacy context if that fails), at a price of not able to have GL support
|
||||
* for the media GStreamer backend.
|
||||
*/
|
||||
if (major < 4 || (major == 4 && minor < 1))
|
||||
hglrc = create_wgl_context_with_attribs (hdc,
|
||||
hglrc_base,
|
||||
share,
|
||||
flags,
|
||||
4,
|
||||
1,
|
||||
is_legacy);
|
||||
|
||||
if (hglrc == NULL)
|
||||
hglrc = create_wgl_context_with_attribs (hdc,
|
||||
hglrc_base,
|
||||
share,
|
||||
flags,
|
||||
major,
|
||||
minor,
|
||||
is_legacy);
|
||||
|
||||
/* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation failed */
|
||||
if (hglrc == NULL)
|
||||
@@ -539,27 +564,10 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
if (!gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, error))
|
||||
return 0;
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||
compat_bit = gdk_gl_context_get_forward_compatible (context);
|
||||
|
||||
/*
|
||||
* We may need a Core GL 4.1+ context in order to use the GL support in
|
||||
* the GStreamer media widget backend (such as on Intel drivers), but
|
||||
* wglCreateContextAttribsARB() may only give us the GL context version
|
||||
* that we ask for here, and nothing more. So, improve things here by
|
||||
* asking for the GL version that is reported to us via epoxy_gl_version(),
|
||||
* rather than the default GL core 3.2 context. Save this up in our
|
||||
* GdkGLContext so that subsequent contexts that are shared with this
|
||||
* context are created likewise too.
|
||||
*/
|
||||
if (share != NULL)
|
||||
gdk_gl_context_get_required_version (share, &major, &minor);
|
||||
else
|
||||
{
|
||||
major = display_win32->gl_version / 10;
|
||||
minor = display_win32->gl_version % 10;
|
||||
}
|
||||
|
||||
if (surface != NULL)
|
||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||
else
|
||||
@@ -626,7 +634,6 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
|
||||
/* Ensure that any other context is created with a legacy bit set */
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
gdk_gl_context_set_required_version (context, major, minor);
|
||||
|
||||
return GDK_GL_API_GL;
|
||||
}
|
||||
@@ -721,10 +728,9 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
|
||||
if (!GDK_IS_WIN32_DISPLAY (display))
|
||||
return FALSE;
|
||||
|
||||
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, NULL))
|
||||
return FALSE;
|
||||
|
||||
display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
if (display_win32->wgl_pixel_format == 0)
|
||||
return FALSE;
|
||||
|
||||
if (major != NULL)
|
||||
*major = display_win32->gl_version / 10;
|
||||
|
||||
@@ -38,6 +38,7 @@ int _gdk_input_ignore_core;
|
||||
|
||||
HKL _gdk_input_locale;
|
||||
gboolean _gdk_input_locale_is_ime = FALSE;
|
||||
UINT _gdk_input_codepage;
|
||||
|
||||
GdkWin32ModalOpKind _modal_operation_in_progress = GDK_WIN32_MODAL_OP_NONE;
|
||||
HWND _modal_move_resize_window = NULL;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Philip Zander
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
#ifndef _WIN64
|
||||
#define GDK_WIN32_COMPILE_FOR_WOW64 1
|
||||
#include "gdkkeys-win32-impl.c"
|
||||
#endif
|
||||
@@ -1,566 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Philip Zander
|
||||
* Copyright (c) 2018 Microsoft
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
/* NOTE: When compiling the 32-bit version of the library, in addition to being
|
||||
* compiled as a regular source file, this file is also included by
|
||||
* gdkkeys-win32-impl-wow64.c to generate an alternate version of the code
|
||||
* intended for running on a 64-bit kernel. Because of the way keyboard layout
|
||||
* DLLs work on Windows, we have to generate two versions and decide at runtime
|
||||
* which code path to execute. You can read more about the specifics below, in
|
||||
* the section about KBD_LONG_POINTER. */
|
||||
|
||||
#include "gdkkeys-win32.h"
|
||||
|
||||
#ifndef GDK_WIN32_COMPILE_FOR_WOW64
|
||||
#define GDK_WIN32_COMPILE_FOR_WOW64 0
|
||||
#endif
|
||||
|
||||
/* This is our equivalent of the KBD_LONG_POINTER macro in Microsoft's kbd.h.
|
||||
*
|
||||
* A KBD_LONG_POINTER represents a pointer native to the *host*.
|
||||
* I.e. 32 bits on 32-bit Windows and 64 bits on 64-bit Windows.
|
||||
*
|
||||
* This is *not* the same as the the bitness of the application, since it is
|
||||
* possible to execute 32-bit binaries on either a 32-bit *or* a 64-bit host.
|
||||
* On a 64-bit host, KBD_LONG_PTR will be 64-bits, even if the application
|
||||
* itself is 32-bit. (Whereas on a 32-bit host, it will be 32-bit.)
|
||||
*
|
||||
* For clarity, here is an overview of the bit-size of KBD_LONG_POINTER on all
|
||||
* possible host & app combinations:
|
||||
*
|
||||
* Host 32 64
|
||||
* App +-----------
|
||||
* 32 | 32 64
|
||||
* 64 | - 64
|
||||
*
|
||||
* In the official MS headers, KBD_LONG_POINTER is implemented via a macro
|
||||
* which expands to the attribute `__ptr64` if the keyboard driver is
|
||||
* compiled for a 64 bit host. Unfortunately, `__ptr64` is only
|
||||
* supported by MSVC. We use a union here as a workaround.
|
||||
*
|
||||
* For all KBD_LONG_POINTERs, we define an alias starting with "KLP".
|
||||
* Our naming schema (inspired by the Windows headers) is thus the following:
|
||||
* - FOO: The type FOO itself
|
||||
* - PFOO: Regular pointer to the type FOO
|
||||
* - KLPFOO: Keyboard Long Pointer to the type FOO
|
||||
*/
|
||||
|
||||
#if GDK_WIN32_COMPILE_FOR_WOW64
|
||||
#define DEFINE_KBD_LONG_POINTER(type) \
|
||||
typedef union { \
|
||||
P##type ptr; \
|
||||
UINT64 _align; \
|
||||
} KLP##type
|
||||
#else
|
||||
#define DEFINE_KBD_LONG_POINTER(type) \
|
||||
typedef union { \
|
||||
P##type ptr; \
|
||||
} KLP##type
|
||||
#endif
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (USHORT);
|
||||
DEFINE_KBD_LONG_POINTER (VOID);
|
||||
|
||||
/* Driver definitions
|
||||
* See
|
||||
* https://github.com/microsoft/windows-rs/blob/0.28.0/crates/deps/sys/src/Windows/Win32/UI/Input/KeyboardAndMouse/mod.rs
|
||||
*
|
||||
* For more information on how these structures work, see also:
|
||||
* https://github.com/microsoft/Windows-driver-samples/tree/f0adcda012820b1cd44a8b3a1953baf478029738/input/layout
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE Vk;
|
||||
BYTE ModBits;
|
||||
} VK_TO_BIT, *PVK_TO_BIT;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_TO_BIT);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KLPVK_TO_BIT pVkToBit;
|
||||
WORD wMaxModBits;
|
||||
BYTE ModNumber[1];
|
||||
} MODIFIERS, *PMODIFIERS;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (MODIFIERS);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE Vsc;
|
||||
USHORT Vk;
|
||||
} VSC_VK, *PVSC_VK;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VSC_VK);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE Vk;
|
||||
BYTE Vsc;
|
||||
} VK_VSC, *PVK_VSC;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_VSC);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE VirtualKey;
|
||||
BYTE Attributes;
|
||||
WCHAR wch[1];
|
||||
} VK_TO_WCHARS, *PVK_TO_WCHARS;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_TO_WCHARS);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KLPVK_TO_WCHARS pVkToWchars;
|
||||
BYTE nModifications;
|
||||
BYTE cbSize;
|
||||
} VK_TO_WCHAR_TABLE, *PVK_TO_WCHAR_TABLE;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (VK_TO_WCHAR_TABLE);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwBoth;
|
||||
WCHAR wchComposed;
|
||||
USHORT uFlags;
|
||||
} DEADKEY, *PDEADKEY;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (DEADKEY);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KLPMODIFIERS pCharModifiers;
|
||||
KLPVK_TO_WCHAR_TABLE pVkToWcharTable;
|
||||
KLPDEADKEY pDeadKey;
|
||||
KLPVOID pKeyNames;
|
||||
KLPVOID pKeyNamesExt;
|
||||
KLPVOID pKeyNamesDead;
|
||||
KLPUSHORT pusVSCtoVK;
|
||||
BYTE bMaxVSCtoVK;
|
||||
KLPVSC_VK pVSCtoVK_E0;
|
||||
KLPVSC_VK pVSCtoVK_E1;
|
||||
DWORD fLocaleFlags;
|
||||
BYTE nLgMaxd;
|
||||
BYTE cbLgEntry;
|
||||
KLPVOID pLigature;
|
||||
} KBDTABLES, *PKBDTABLES;
|
||||
|
||||
DEFINE_KBD_LONG_POINTER (KBDTABLES);
|
||||
|
||||
/* End of declarations */
|
||||
|
||||
static BYTE
|
||||
keystate_to_modbits (GdkWin32KeymapLayoutInfo *info,
|
||||
const BYTE keystate[256])
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
PVK_TO_BIT vk_to_bit;
|
||||
BYTE result = 0;
|
||||
int i;
|
||||
|
||||
if (tables == NULL)
|
||||
return 0;
|
||||
|
||||
vk_to_bit = tables->pCharModifiers.ptr->pVkToBit.ptr;
|
||||
|
||||
for (i = 0; vk_to_bit[i].Vk != 0; ++i)
|
||||
if (keystate[vk_to_bit[i].Vk] & 0x80)
|
||||
result |= vk_to_bit[i].ModBits;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static BYTE
|
||||
modbits_to_level (GdkWin32KeymapLayoutInfo *info,
|
||||
BYTE modbits)
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
PMODIFIERS modifiers;
|
||||
|
||||
if (tables == NULL)
|
||||
return 0;
|
||||
|
||||
modifiers = tables->pCharModifiers.ptr;
|
||||
if (modbits > modifiers->wMaxModBits)
|
||||
return 0;
|
||||
|
||||
return modifiers->ModNumber[modbits];
|
||||
}
|
||||
|
||||
#define POPCOUNT(b) (!!(b & 0x01) + !!(b & 0x02) + !!(b & 0x04) + !!(b & 0x08) + \
|
||||
!!(b & 0x10) + !!(b & 0x20) + !!(b & 0x40) + !!(b & 0x80))
|
||||
|
||||
/*
|
||||
* vk_to_char_fuzzy:
|
||||
*
|
||||
* For a given key and modifier state, return the best-fit character and the
|
||||
* modifiers used to produce it. Note that not all modifiers need to be used,
|
||||
* because some modifier combination aren't actually mapped in the keyboard
|
||||
* layout (for example the Ctrl key typically has no effect, unless used in
|
||||
* combination with Alt). Such modifiers will not be consumed.
|
||||
*
|
||||
* 'Best-fit' means 'consume as many modifiers as possibe'.
|
||||
*
|
||||
* For example (assuming a neutral lock state):
|
||||
*
|
||||
* - a -> 'a', consumed_mod_bits: []
|
||||
* - Shift + a -> 'A', consumed_mod_bits: [Shift]
|
||||
* - Ctrl + a -> 'a', consumed_mod_bits: []
|
||||
* - Ctrl + Shift + a -> 'A', consumed_mod_bits: [Shift]
|
||||
*
|
||||
* If capslock is active, the result could be:
|
||||
*
|
||||
* - a -> 'A', consumed_mod_bits: [Shift]
|
||||
* - Shift + a -> 'a', consumed_mod_bits: []
|
||||
* - Ctrl + a -> 'a', consumed_mod_bits: []
|
||||
* - Ctrl + Shift + a -> 'A', consumed_mod_bits: [Shift]
|
||||
*
|
||||
* The held down modifiers are supplied in `mod_bits` as a bitmask of KBDSHIFT,
|
||||
* KBDCTRL, KBDALT etc.
|
||||
*
|
||||
* The toggled modifiers are supplied in `lock_state` as a bitmask of CAPLOK and KANALOK.
|
||||
*
|
||||
* If the key combination results in a dead key, `is_dead` will be set to TRUE,
|
||||
* otherwise it will be set to FALSE.
|
||||
*/
|
||||
static WCHAR
|
||||
vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info,
|
||||
BYTE mod_bits,
|
||||
BYTE lock_bits,
|
||||
BYTE *consumed_mod_bits,
|
||||
gboolean *is_dead,
|
||||
BYTE vk)
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
|
||||
PVK_TO_WCHAR_TABLE wch_tables;
|
||||
PVK_TO_WCHAR_TABLE wch_table;
|
||||
PVK_TO_WCHARS entry;
|
||||
|
||||
int table_index;
|
||||
int entry_index;
|
||||
int n_levels;
|
||||
int entry_size;
|
||||
|
||||
/* Initialize with defaults */
|
||||
if (consumed_mod_bits)
|
||||
*consumed_mod_bits = 0;
|
||||
if (is_dead)
|
||||
*is_dead = FALSE;
|
||||
|
||||
if (tables == NULL)
|
||||
return WCH_NONE;
|
||||
|
||||
wch_tables = tables->pVkToWcharTable.ptr;
|
||||
|
||||
table_index = info->vk_lookup_table[vk].table;
|
||||
entry_index = info->vk_lookup_table[vk].index;
|
||||
|
||||
if (table_index == -1 || entry_index == -1)
|
||||
return WCH_NONE;
|
||||
|
||||
wch_table = &wch_tables[table_index];
|
||||
|
||||
n_levels = wch_table->nModifications;
|
||||
entry_size = wch_table->cbSize;
|
||||
|
||||
entry = (PVK_TO_WCHARS) ((PBYTE) wch_table->pVkToWchars.ptr
|
||||
+ entry_size*entry_index);
|
||||
|
||||
if (entry->VirtualKey == vk)
|
||||
{
|
||||
gboolean have_sgcaps = FALSE;
|
||||
WCHAR best_char = WCH_NONE;
|
||||
BYTE best_modifiers = 0;
|
||||
int best_score = -1;
|
||||
gboolean best_is_dead = FALSE;
|
||||
int level;
|
||||
|
||||
/* Take toggled keys into account. For example, capslock normally inverts the
|
||||
* state of KBDSHIFT (with some exceptions). */
|
||||
|
||||
/* Key supporting capslock */
|
||||
if ((entry->Attributes & CAPLOK) &&
|
||||
/* Ignore capslock if any modifiers other than shift are pressed.
|
||||
* E.g. on the German layout, CapsLock + AltGr + q is the same as
|
||||
* AltGr + q ('@'), but NOT the same as Shift + AltGr + q (not mapped). */
|
||||
!(mod_bits & ~KBDSHIFT) &&
|
||||
(lock_bits & CAPLOK))
|
||||
mod_bits ^= KBDSHIFT;
|
||||
|
||||
/* Key supporting combination of capslock + altgr */
|
||||
if ((entry->Attributes & CAPLOKALTGR) &&
|
||||
(mod_bits & KBDALTGR) &&
|
||||
(lock_bits & CAPLOK))
|
||||
mod_bits ^= KBDSHIFT;
|
||||
|
||||
/* In the Swiss German layout, CapsLock + key is different from Shift + key
|
||||
* for some keys. For such keys, the characters for active capslock are
|
||||
* in the next entry. */
|
||||
if ((entry->Attributes & SGCAPS) &&
|
||||
(lock_bits & CAPLOK))
|
||||
have_sgcaps = TRUE;
|
||||
|
||||
/* I'm not totally sure how kanalok behaves, for now I assume that there
|
||||
* aren't any special cases. */
|
||||
if ((entry->Attributes & KANALOK) &&
|
||||
(lock_bits & KANALOK))
|
||||
mod_bits ^= KBDKANA;
|
||||
|
||||
/* We try to find the entry with the most matching modifiers */
|
||||
for (level = 0; level < n_levels; ++level)
|
||||
{
|
||||
BYTE candidate_modbits = info->level_to_modbits[level];
|
||||
gboolean candidate_is_dead = FALSE;
|
||||
WCHAR c;
|
||||
int score;
|
||||
|
||||
if (candidate_modbits & ~mod_bits)
|
||||
continue;
|
||||
|
||||
/* Some keys have bogus mappings for the control key, e.g. Ctrl +
|
||||
* Backspace = Delete, Ctrl + [ = 0x1B or even Ctrl + Shift + 6 =
|
||||
* 0x1E on a US keyboard. So we have to ignore all cases of
|
||||
* Ctrl that aren't part of AltGr.
|
||||
*/
|
||||
if ((candidate_modbits & KBDCTRL) && !(candidate_modbits & KBDALT))
|
||||
continue;
|
||||
|
||||
c = entry->wch[level];
|
||||
if (c == WCH_DEAD || have_sgcaps)
|
||||
{
|
||||
/* Next entry contains the undead/capslocked keys */
|
||||
PVK_TO_WCHARS next_entry;
|
||||
next_entry = (PVK_TO_WCHARS) ((PBYTE) wch_table->pVkToWchars.ptr
|
||||
+ entry_size * (entry_index + 1));
|
||||
c = next_entry->wch[level];
|
||||
candidate_is_dead = TRUE;
|
||||
}
|
||||
|
||||
if (c == WCH_DEAD || c == WCH_LGTR || c == WCH_NONE)
|
||||
continue;
|
||||
|
||||
score = POPCOUNT (candidate_modbits & mod_bits);
|
||||
if (score > best_score)
|
||||
{
|
||||
best_score = score;
|
||||
best_char = c;
|
||||
best_modifiers = candidate_modbits;
|
||||
best_is_dead = candidate_is_dead;
|
||||
}
|
||||
}
|
||||
|
||||
if (consumed_mod_bits)
|
||||
*consumed_mod_bits = best_modifiers;
|
||||
|
||||
if (is_dead)
|
||||
*is_dead = best_is_dead;
|
||||
|
||||
return best_char;
|
||||
}
|
||||
|
||||
return WCH_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_vk_lookup_table (GdkWin32KeymapLayoutInfo *info)
|
||||
{
|
||||
PKBDTABLES tables = (PKBDTABLES) info->tables;
|
||||
PVK_TO_WCHAR_TABLE wch_tables;
|
||||
PMODIFIERS modifiers;
|
||||
int i, vk, table_idx;
|
||||
|
||||
g_return_if_fail (tables != NULL);
|
||||
|
||||
wch_tables = tables->pVkToWcharTable.ptr;
|
||||
|
||||
/* Initialize empty table */
|
||||
memset (info->vk_lookup_table, -1, sizeof (info->vk_lookup_table));
|
||||
|
||||
/* Initialize level -> modbits lookup table */
|
||||
memset (info->level_to_modbits, 0, sizeof(info->level_to_modbits));
|
||||
info->max_level = 0;
|
||||
|
||||
modifiers = tables->pCharModifiers.ptr;
|
||||
for (i = 0; i <= modifiers->wMaxModBits; ++i)
|
||||
{
|
||||
if (modifiers->ModNumber[i] != SHFT_INVALID &&
|
||||
modifiers->ModNumber[i] != 0 /* Workaround for buggy layouts*/)
|
||||
{
|
||||
if (modifiers->ModNumber[i] > info->max_level)
|
||||
info->max_level = modifiers->ModNumber[i];
|
||||
info->level_to_modbits[modifiers->ModNumber[i]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
info->max_modbit_value = modifiers->wMaxModBits;
|
||||
|
||||
/* For convenience, we add 256 identity-mapped entries corresponding to the VKs.
|
||||
* This allows us to return a pointer to them from the `gdk_keysym_to_key_entry`
|
||||
* function.
|
||||
*/
|
||||
|
||||
for (vk = 0; vk < 256; ++vk)
|
||||
{
|
||||
GdkWin32KeymapKeyEntry key_entry = {0};
|
||||
key_entry.vk = vk;
|
||||
key_entry.mod_bits = 0;
|
||||
key_entry.next = -1;
|
||||
g_array_append_val (info->key_entries, key_entry);
|
||||
}
|
||||
|
||||
/* Special entry for ISO_Left_Tab */
|
||||
{
|
||||
GdkWin32KeymapKeyEntry key_entry = {0};
|
||||
key_entry.vk = VK_TAB;
|
||||
key_entry.mod_bits = KBDSHIFT;
|
||||
key_entry.next = -1;
|
||||
g_array_append_val (info->key_entries, key_entry);
|
||||
}
|
||||
|
||||
/* Initialize generic vk <-> char tables */
|
||||
|
||||
for (table_idx = 0; ; ++table_idx)
|
||||
{
|
||||
PVK_TO_WCHAR_TABLE wch_table = &wch_tables[table_idx];
|
||||
int entry_size;
|
||||
int n_levels;
|
||||
int entry_idx;
|
||||
|
||||
if (wch_table->pVkToWchars.ptr == NULL)
|
||||
break;
|
||||
|
||||
entry_size = wch_table->cbSize;
|
||||
n_levels = wch_table->nModifications;
|
||||
|
||||
for (entry_idx = 0; ; ++entry_idx)
|
||||
{
|
||||
PVK_TO_WCHARS entry;
|
||||
int level;
|
||||
|
||||
entry = (PVK_TO_WCHARS) ((PBYTE) wch_table->pVkToWchars.ptr
|
||||
+ entry_size * entry_idx);
|
||||
|
||||
if (entry->VirtualKey == 0)
|
||||
break;
|
||||
|
||||
/* Lookup table to find entry for a VK in O(1). */
|
||||
|
||||
/* Only add the first entry, as some layouts (Swiss German) contain
|
||||
* multiple successive entries for the same VK (SGCAPS). */
|
||||
if (info->vk_lookup_table[entry->VirtualKey].table < 0)
|
||||
{
|
||||
info->vk_lookup_table[entry->VirtualKey].table = table_idx;
|
||||
info->vk_lookup_table[entry->VirtualKey].index = entry_idx;
|
||||
}
|
||||
|
||||
/* Create reverse lookup entries to find a VK+modifier combinations
|
||||
* that results in a given character. */
|
||||
for (level = 0; level < n_levels; ++level)
|
||||
{
|
||||
GdkWin32KeymapKeyEntry key_entry = {0};
|
||||
WCHAR c = entry->wch[level];
|
||||
int inserted_idx;
|
||||
gintptr next_idx;
|
||||
|
||||
key_entry.vk = entry->VirtualKey;
|
||||
key_entry.mod_bits = info->level_to_modbits[level];
|
||||
|
||||
/* There can be multiple combinations that produce the same character.
|
||||
* We store all of them in a linked list.
|
||||
* Check if we already have an entry for the character, so we can chain
|
||||
* them together. */
|
||||
if (g_hash_table_lookup_extended (info->reverse_lookup_table,
|
||||
GINT_TO_POINTER (c),
|
||||
NULL, (gpointer*)&next_idx))
|
||||
{
|
||||
key_entry.next = next_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_entry.next = -1;
|
||||
}
|
||||
|
||||
/* We store the KeyEntry in an array. In the hash table we only store
|
||||
* the index. */
|
||||
|
||||
g_array_append_val (info->key_entries, key_entry);
|
||||
inserted_idx = info->key_entries->len - 1;
|
||||
|
||||
g_hash_table_insert (info->reverse_lookup_table,
|
||||
GINT_TO_POINTER (c),
|
||||
GINT_TO_POINTER (inserted_idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_layout_dll (const char *dll,
|
||||
GdkWin32KeymapLayoutInfo *info)
|
||||
{
|
||||
typedef KLPKBDTABLES (*KbdLayerDescriptor)(VOID);
|
||||
|
||||
HMODULE lib;
|
||||
KbdLayerDescriptor func;
|
||||
KLPKBDTABLES tables;
|
||||
|
||||
g_return_val_if_fail (dll != NULL, FALSE);
|
||||
|
||||
lib = LoadLibraryA (dll);
|
||||
if (lib == NULL)
|
||||
goto fail1;
|
||||
|
||||
func = (KbdLayerDescriptor) GetProcAddress (lib, "KbdLayerDescriptor");
|
||||
if (func == NULL)
|
||||
goto fail2;
|
||||
|
||||
tables = func();
|
||||
|
||||
info->lib = lib;
|
||||
info->tables = (PKBDTABLES) tables.ptr;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail2:
|
||||
FreeLibrary (lib);
|
||||
fail1:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if GDK_WIN32_COMPILE_FOR_WOW64
|
||||
#define GDK_WIN32_KEYMAP_IMPL_NAME gdkwin32_keymap_impl_wow64
|
||||
#else
|
||||
#define GDK_WIN32_KEYMAP_IMPL_NAME gdkwin32_keymap_impl
|
||||
#endif
|
||||
|
||||
const GdkWin32KeymapImpl GDK_WIN32_KEYMAP_IMPL_NAME =
|
||||
{
|
||||
load_layout_dll,
|
||||
init_vk_lookup_table,
|
||||
keystate_to_modbits,
|
||||
modbits_to_level,
|
||||
vk_to_char_fuzzy
|
||||
};
|
||||
+1301
-720
File diff suppressed because it is too large
Load Diff
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Philip Zander
|
||||
* Copyright (c) 2018 Microsoft
|
||||
*
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* For lookup table VK -> chars */
|
||||
typedef struct
|
||||
{
|
||||
int table;
|
||||
int index;
|
||||
} GdkWin32KeymapTableAndIndex;
|
||||
|
||||
/* For reverse lookup char -> VKs */
|
||||
typedef struct
|
||||
{
|
||||
BYTE mod_bits;
|
||||
BYTE vk;
|
||||
|
||||
/* Index of next KeyEntry. -1 if there is no next entry. */
|
||||
int next;
|
||||
} GdkWin32KeymapKeyEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HKL handle;
|
||||
|
||||
/* Keyboard layout identifier */
|
||||
char name[KL_NAMELENGTH];
|
||||
|
||||
/* Path of the layout DLL */
|
||||
char *file;
|
||||
|
||||
/* Handle of the layout DLL */
|
||||
HINSTANCE lib;
|
||||
|
||||
/* The actual conversion tables provided by the layout DLL.
|
||||
*
|
||||
* This is a pointer to a KBDTABLES structure. The exact definition
|
||||
* of this structure depends on the kernel on which the executable
|
||||
* run and can in general only be determined at runtime. That's why
|
||||
* we have to use a generic gpointer instead of the actual type here.
|
||||
*
|
||||
* See comment on GdkWin32KeymapImpl below for more information. */
|
||||
gpointer tables;
|
||||
|
||||
/* VK -> chars lookup table so we don't have to do a linear scan
|
||||
* every time we look up a key. */
|
||||
GdkWin32KeymapTableAndIndex vk_lookup_table[256];
|
||||
|
||||
/* List of entries for reverse (char ->VKs) lookup. */
|
||||
GArray *key_entries;
|
||||
|
||||
/* Reverse lookup table (char -> VKs). Key: Unichar. Value: int.
|
||||
* The value is used to index into the key_entries array. The key_entries
|
||||
* array can contain multiple consecutive entries for a given char.
|
||||
* The end of the list for the char is marked by a key entry that has
|
||||
* mod_bits and vk set to 0xFF. */
|
||||
GHashTable *reverse_lookup_table;
|
||||
|
||||
/* Map level to modbits */
|
||||
BYTE level_to_modbits[256];
|
||||
|
||||
/* Max Number of levels */
|
||||
BYTE max_level;
|
||||
|
||||
/* Maximum possible value of a modbits bitset. */
|
||||
BYTE max_modbit_value;
|
||||
|
||||
} GdkWin32KeymapLayoutInfo;
|
||||
|
||||
/* Some keyboard driver constants
|
||||
* See https://github.com/microsoft/windows-rs/blob/0.28.0/crates/deps/sys/src/Windows/Win32/UI/Input/KeyboardAndMouse/mod.rs
|
||||
*/
|
||||
|
||||
/* Modifier bits */
|
||||
#define KBDBASE 0x00
|
||||
#define KBDSHIFT 0x01
|
||||
#define KBDCTRL 0x02
|
||||
#define KBDALT 0x04
|
||||
#define KBDKANA 0x08
|
||||
#define KBDROYA 0x10
|
||||
#define KBDLOYA 0x20
|
||||
#define KBDGRPSELTAP 0x80
|
||||
|
||||
#define KBDALTGR (KBDCTRL| KBDALT)
|
||||
|
||||
/* */
|
||||
#define SHFT_INVALID 0x0F
|
||||
|
||||
/* Char table constants */
|
||||
#define WCH_NONE 0xF000
|
||||
#define WCH_DEAD 0xF001
|
||||
#define WCH_LGTR 0xF002
|
||||
|
||||
/* Char table flags */
|
||||
#define CAPLOK 0x01
|
||||
#define SGCAPS 0x02
|
||||
#define CAPLOKALTGR 0x04
|
||||
#define KANALOK 0x08
|
||||
#define GRPSELTAP 0x80
|
||||
|
||||
/* IMPORTANT:
|
||||
*
|
||||
* Keyboard layout DLLs are dependent on the host architecture.
|
||||
*
|
||||
* - 32 bit systems have just one 32 bit DLL in System32.
|
||||
* - 64 bit systems contain two versions of each layout DLL: One in System32
|
||||
* for 64-bit applications, and one in SysWOW64 for 32-bit applications.
|
||||
*
|
||||
* Here comes the tricky part:
|
||||
*
|
||||
* The 32-bit DLL in SysWOW64 is *not* identical to the DLL you would find
|
||||
* on a true 32 bit system, because all the pointers there are declared with
|
||||
* the attribute `__ptr64` (which means they are 64 bits wide, but only the
|
||||
* lower 32 bits are used).
|
||||
*
|
||||
* This leads to the following problems:
|
||||
*
|
||||
* (1) GCC does not support `__ptr64`
|
||||
* (2) When compiling the 32-bit library, we need two versions of the same code
|
||||
* and decide at run-time which one to execute, because we can't know at
|
||||
* compile time whether we will be running on a true 32-bit system, or on
|
||||
* WOW64.
|
||||
*
|
||||
* To solve this problem, we generate code for both cases (see
|
||||
* gdkkeys-win32-impl.c + gdkkeys-win32-impl-wow64.c) and encapsulate
|
||||
* the resulting functions in a struct of type GdkWin32KeymapImpl,
|
||||
* allowing us to select the correct implementation at runtime.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean (*load_layout_dll) (const char *dll,
|
||||
GdkWin32KeymapLayoutInfo *info);
|
||||
void (*init_vk_lookup_table) (GdkWin32KeymapLayoutInfo *info);
|
||||
BYTE (*keystate_to_modbits) (GdkWin32KeymapLayoutInfo *info,
|
||||
const BYTE keystate[256]);
|
||||
BYTE (*modbits_to_level) (GdkWin32KeymapLayoutInfo *info,
|
||||
BYTE modbits);
|
||||
WCHAR (*vk_to_char_fuzzy) (GdkWin32KeymapLayoutInfo *info,
|
||||
BYTE mod_bits,
|
||||
BYTE lock_bits,
|
||||
BYTE *consumed_mod_bits,
|
||||
gboolean *is_dead,
|
||||
BYTE vk);
|
||||
} GdkWin32KeymapImpl;
|
||||
@@ -52,9 +52,7 @@ static gboolean gdk_synchronize = FALSE;
|
||||
void
|
||||
_gdk_win32_surfaceing_init (void)
|
||||
{
|
||||
GdkWin32Keymap *win32_keymap;
|
||||
|
||||
win32_keymap = GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display));
|
||||
char buf[10];
|
||||
|
||||
if (gdk_synchronize)
|
||||
GdiSetBatchLimit (1);
|
||||
@@ -62,9 +60,13 @@ _gdk_win32_surfaceing_init (void)
|
||||
_gdk_app_hmodule = GetModuleHandle (NULL);
|
||||
_gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
|
||||
_gdk_input_locale = GetKeyboardLayout (0);
|
||||
_gdk_win32_keymap_set_active_layout (win32_keymap, _gdk_input_locale);
|
||||
|
||||
GDK_NOTE (EVENTS, g_print ("input_locale: %p\n", _gdk_input_locale));
|
||||
_gdk_win32_keymap_set_active_layout (GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display)), _gdk_input_locale);
|
||||
GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
|
||||
LOCALE_IDEFAULTANSICODEPAGE,
|
||||
buf, sizeof (buf));
|
||||
_gdk_input_codepage = atoi (buf);
|
||||
GDK_NOTE (EVENTS, g_print ("input_locale:%p, codepage:%d\n",
|
||||
_gdk_input_locale, _gdk_input_codepage));
|
||||
|
||||
_gdk_win32_clipdrop_init ();
|
||||
}
|
||||
|
||||
@@ -269,6 +269,7 @@ extern int _gdk_input_ignore_core;
|
||||
*/
|
||||
extern HKL _gdk_input_locale;
|
||||
extern gboolean _gdk_input_locale_is_ime;
|
||||
extern UINT _gdk_input_codepage;
|
||||
|
||||
extern guint _gdk_keymap_serial;
|
||||
|
||||
@@ -350,11 +351,12 @@ GList *_gdk_win32_display_list_devices (GdkDisplay *dpy);
|
||||
gboolean _gdk_win32_display_has_pending (GdkDisplay *display);
|
||||
void _gdk_win32_display_queue_events (GdkDisplay *display);
|
||||
|
||||
gboolean _gdk_win32_keymap_has_altgr (GdkWin32Keymap *keymap);
|
||||
guint8 _gdk_win32_keymap_get_active_group (GdkWin32Keymap *keymap);
|
||||
guint8 _gdk_win32_keymap_get_rshift_scancode (GdkWin32Keymap *keymap);
|
||||
void _gdk_win32_keymap_set_active_layout (GdkWin32Keymap *keymap,
|
||||
HKL hkl);
|
||||
GdkModifierType _gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap);
|
||||
|
||||
|
||||
GdkKeymap *_gdk_win32_display_get_keymap (GdkDisplay *display);
|
||||
|
||||
@@ -423,12 +425,4 @@ void _gdk_win32_surfaceing_init (void);
|
||||
void _gdk_drag_init (void);
|
||||
void _gdk_events_init (GdkDisplay *display);
|
||||
|
||||
typedef enum _GdkWin32ProcessorCheckType
|
||||
{
|
||||
GDK_WIN32_ARM64,
|
||||
GDK_WIN32_WOW64,
|
||||
} GdkWin32ProcessorCheckType;
|
||||
|
||||
gboolean _gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type);
|
||||
|
||||
#endif /* __GDK_PRIVATE_WIN32_H__ */
|
||||
|
||||
+140
-140
@@ -653,7 +653,6 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
|
||||
g_object_unref (frame_clock);
|
||||
impl->hdc = GetDC (impl->handle);
|
||||
impl->inhibit_configure = TRUE;
|
||||
|
||||
return surface;
|
||||
}
|
||||
@@ -787,6 +786,26 @@ show_window_internal (GdkSurface *window,
|
||||
if (!unminimize && !already_mapped && IsWindowVisible (GDK_SURFACE_HWND (window)))
|
||||
return;
|
||||
|
||||
/* Other cases */
|
||||
|
||||
exstyle = GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE);
|
||||
|
||||
/* Use SetWindowPos to show transparent windows so automatic redraws
|
||||
* in other windows can be suppressed.
|
||||
*/
|
||||
if (exstyle & WS_EX_TRANSPARENT)
|
||||
{
|
||||
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
||||
|
||||
if (GDK_IS_DRAG_SURFACE (window))
|
||||
flags |= SWP_NOACTIVATE;
|
||||
|
||||
SetWindowPos (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED, 0, 0, 0, 0, flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* For initial map of "normal" windows we want to emulate WM window
|
||||
* positioning behaviour, which means:
|
||||
* + default to the initial CW_USEDEFAULT placement,
|
||||
@@ -933,8 +952,6 @@ show_window_internal (GdkSurface *window,
|
||||
GtkShowWindow (window, SW_SHOW);
|
||||
}
|
||||
|
||||
exstyle = GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE);
|
||||
|
||||
/* Sync STATE_ABOVE to TOPMOST */
|
||||
if (!GDK_IS_DRAG_SURFACE (window) &&
|
||||
(((window->state & GDK_TOPLEVEL_STATE_ABOVE) &&
|
||||
@@ -971,7 +988,22 @@ gdk_win32_surface_hide (GdkSurface *window)
|
||||
|
||||
_gdk_surface_clear_update_area (window);
|
||||
|
||||
GtkShowWindow (window, SW_HIDE);
|
||||
if (GDK_IS_TOPLEVEL (window))
|
||||
ShowOwnedPopups (GDK_SURFACE_HWND (window), FALSE);
|
||||
|
||||
/* Use SetWindowPos to hide transparent windows so automatic redraws
|
||||
* in other windows can be suppressed.
|
||||
*/
|
||||
if (GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
|
||||
{
|
||||
SetWindowPos (GDK_SURFACE_HWND (window), SWP_NOZORDER_SPECIFIED,
|
||||
0, 0, 0, 0,
|
||||
SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkShowWindow (window, SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1010,15 +1042,14 @@ gdk_win32_surface_do_move (GdkSurface *window,
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_resize (GdkSurface *surface,
|
||||
int width,
|
||||
int height)
|
||||
gdk_win32_surface_resize (GdkSurface *window,
|
||||
int width, int height)
|
||||
{
|
||||
RECT outer_rect;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
if (width < 1)
|
||||
@@ -1027,29 +1058,28 @@ gdk_win32_surface_resize (GdkSurface *surface,
|
||||
height = 1;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_win32_surface_resize: %p: %dx%d\n",
|
||||
GDK_SURFACE_HWND (surface), width, height));
|
||||
GDK_SURFACE_HWND (window), width, height));
|
||||
|
||||
if (surface->state & GDK_TOPLEVEL_STATE_FULLSCREEN)
|
||||
if (window->state & GDK_TOPLEVEL_STATE_FULLSCREEN)
|
||||
return;
|
||||
|
||||
get_outer_rect (surface, width, height, &outer_rect);
|
||||
get_outer_rect (window, width, height, &outer_rect);
|
||||
|
||||
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
|
||||
"NOACTIVATE|NOMOVE|NOZORDER)\n",
|
||||
GDK_SURFACE_HWND (surface),
|
||||
GDK_SURFACE_HWND (window),
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top));
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
0, 0,
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
|
||||
surface->resize_count += 1;
|
||||
window->resize_count += 1;
|
||||
|
||||
if (!GDK_WIN32_SURFACE (surface)->force_recompute_size)
|
||||
gdk_surface_request_layout (surface);
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1303,22 +1333,33 @@ gdk_win32_surface_set_urgency_hint (GdkSurface *window,
|
||||
gboolean urgent)
|
||||
{
|
||||
FLASHWINFO flashwinfo;
|
||||
typedef BOOL (WINAPI *PFN_FlashWindowEx) (FLASHWINFO*);
|
||||
PFN_FlashWindowEx flashWindowEx = NULL;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
flashwinfo.cbSize = sizeof (flashwinfo);
|
||||
flashwinfo.hwnd = GDK_SURFACE_HWND (window);
|
||||
if (urgent)
|
||||
flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
|
||||
else
|
||||
flashwinfo.dwFlags = FLASHW_STOP;
|
||||
flashwinfo.uCount = 0;
|
||||
flashwinfo.dwTimeout = 0;
|
||||
flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
|
||||
|
||||
FlashWindowEx (&flashwinfo);
|
||||
if (flashWindowEx)
|
||||
{
|
||||
flashwinfo.cbSize = sizeof (flashwinfo);
|
||||
flashwinfo.hwnd = GDK_SURFACE_HWND (window);
|
||||
if (urgent)
|
||||
flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
|
||||
else
|
||||
flashwinfo.dwFlags = FLASHW_STOP;
|
||||
flashwinfo.uCount = 0;
|
||||
flashwinfo.dwTimeout = 0;
|
||||
|
||||
flashWindowEx (&flashwinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
FlashWindow (GDK_SURFACE_HWND (window), urgent);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2454,41 +2495,35 @@ _gdk_win32_surface_handle_aerosnap (GdkSurface *window,
|
||||
}
|
||||
|
||||
static void
|
||||
apply_snap (GdkSurface *surface,
|
||||
GdkWin32AeroSnapState snap)
|
||||
apply_snap (GdkSurface *window,
|
||||
GdkWin32AeroSnapState snap)
|
||||
{
|
||||
GdkMonitor *monitor;
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
display = gdk_surface_get_display (window);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
|
||||
switch (snap)
|
||||
{
|
||||
case GDK_WIN32_AEROSNAP_STATE_UNDETERMINED:
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_MAXIMIZE:
|
||||
unsnap (surface, monitor);
|
||||
gdk_win32_surface_maximize (surface);
|
||||
unsnap (window, monitor);
|
||||
gdk_win32_surface_maximize (window);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_HALFLEFT:
|
||||
unsnap (surface, monitor);
|
||||
snap_left (surface, monitor, monitor);
|
||||
unsnap (window, monitor);
|
||||
snap_left (window, monitor, monitor);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_HALFRIGHT:
|
||||
unsnap (surface, monitor);
|
||||
snap_right (surface, monitor, monitor);
|
||||
unsnap (window, monitor);
|
||||
snap_right (window, monitor, monitor);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_FULLUP:
|
||||
snap_up (surface);
|
||||
snap_up (window);
|
||||
break;
|
||||
}
|
||||
|
||||
if (snap != GDK_WIN32_AEROSNAP_STATE_UNDETERMINED)
|
||||
{
|
||||
GDK_WIN32_SURFACE (surface)->inhibit_configure = TRUE;
|
||||
GDK_WIN32_SURFACE (surface)->force_recompute_size = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Registers a dumb window class. This window
|
||||
@@ -3368,10 +3403,10 @@ get_cursor_name_from_op (GdkW32WindowDragOp op,
|
||||
}
|
||||
|
||||
static void
|
||||
setup_drag_move_resize_context (GdkSurface *surface,
|
||||
setup_drag_move_resize_context (GdkSurface *window,
|
||||
GdkW32DragMoveResizeContext *context,
|
||||
GdkW32WindowDragOp op,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkDevice *device,
|
||||
int button,
|
||||
double x,
|
||||
@@ -3380,13 +3415,12 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
{
|
||||
RECT rect;
|
||||
const char *cursor_name;
|
||||
GdkSurface *pointer_surface;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
gboolean maximized = gdk_toplevel_get_state (GDK_TOPLEVEL (surface)) & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
GdkSurface *pointer_window;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (window);
|
||||
gboolean maximized = gdk_toplevel_get_state (GDK_TOPLEVEL (window)) & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
int root_x, root_y;
|
||||
gboolean restore_configure = FALSE;
|
||||
|
||||
gdk_win32_surface_get_root_coords (surface, x, y, &root_x, &root_y);
|
||||
gdk_win32_surface_get_root_coords (window, x, y, &root_x, &root_y);
|
||||
|
||||
/* Before we drag, we need to undo any maximization or snapping.
|
||||
* AeroSnap behaviour:
|
||||
@@ -3409,7 +3443,7 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
* resize
|
||||
* don't unsnap
|
||||
* apply new width and x position to unsnapped cache,
|
||||
* so that unsnapped surface only regains its height
|
||||
* so that unsnapped window only regains its height
|
||||
* and y position, but inherits x and width from
|
||||
* the fullup snapped state
|
||||
* vertical resize:
|
||||
@@ -3424,7 +3458,7 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
*
|
||||
* TODO: make this implementation behave as AeroSnap on resizes?
|
||||
* There's also the case where
|
||||
* a halfleft/halfright surface isn't unsnapped when it's
|
||||
* a halfleft/halfright window isn't unsnapped when it's
|
||||
* being moved horizontally, but it's more difficult to implement.
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_RESIZE &&
|
||||
@@ -3432,8 +3466,7 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
impl->snap_state == GDK_WIN32_AEROSNAP_STATE_HALFLEFT ||
|
||||
impl->snap_state == GDK_WIN32_AEROSNAP_STATE_FULLUP))
|
||||
{
|
||||
discard_snapinfo (surface);
|
||||
restore_configure = TRUE;
|
||||
discard_snapinfo (window);
|
||||
}
|
||||
else if (maximized ||
|
||||
(impl->snap_state == GDK_WIN32_AEROSNAP_STATE_HALFRIGHT ||
|
||||
@@ -3443,25 +3476,24 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
GdkMonitor *monitor;
|
||||
int wx, wy, wwidth, wheight;
|
||||
int swx, swy, swwidth, swheight;
|
||||
gboolean pointer_outside_of_surface;
|
||||
gboolean pointer_outside_of_window;
|
||||
int offsetx, offsety;
|
||||
gboolean left_half;
|
||||
GdkDisplay *display;
|
||||
|
||||
restore_configure = TRUE;
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
gdk_surface_get_geometry (surface, &wx, &wy, &wwidth, &wheight);
|
||||
display = gdk_surface_get_display (window);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
gdk_surface_get_geometry (window, &wx, &wy, &wwidth, &wheight);
|
||||
|
||||
swx = wx;
|
||||
swy = wy;
|
||||
swwidth = wwidth;
|
||||
swheight = wheight;
|
||||
|
||||
/* Subtract surface shadow. We don't want pointer to go outside of
|
||||
* the visible surface during drag-move. For drag-resize it's OK.
|
||||
* Don't take shadow into account if the surface is maximized -
|
||||
* maximized surfaces don't have shadows.
|
||||
/* Subtract window shadow. We don't want pointer to go outside of
|
||||
* the visible window during drag-move. For drag-resize it's OK.
|
||||
* Don't take shadow into account if the window is maximized -
|
||||
* maximized windows don't have shadows.
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE && !maximized)
|
||||
{
|
||||
@@ -3471,16 +3503,16 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
swheight -= impl->shadow_y;
|
||||
}
|
||||
|
||||
pointer_outside_of_surface = root_x < swx || root_x > swx + swwidth ||
|
||||
pointer_outside_of_window = root_x < swx || root_x > swx + swwidth ||
|
||||
root_y < swy || root_y > swy + swheight;
|
||||
/* Calculate the offset of the pointer relative to the surface */
|
||||
/* Calculate the offset of the pointer relative to the window */
|
||||
offsetx = root_x - swx;
|
||||
offsety = root_y - swy;
|
||||
|
||||
/* Figure out in which half of the surface the pointer is.
|
||||
/* Figure out in which half of the window the pointer is.
|
||||
* The code currently only concerns itself with horizontal
|
||||
* dimension (left/right halves).
|
||||
* There's no upper/lower half, because usually surface
|
||||
* There's no upper/lower half, because usually window
|
||||
* is dragged by its upper half anyway. If that changes, adjust
|
||||
* accordingly.
|
||||
*/
|
||||
@@ -3490,26 +3522,26 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
if (!left_half)
|
||||
offsetx = swwidth - offsetx;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d, this is %d : %d relative to the surface's %s\n",
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d, this is %d : %d relative to the window's %s\n",
|
||||
root_x, root_y, offsetx, offsety,
|
||||
left_half ? "left half" : "right half"));
|
||||
|
||||
/* Move surface in such a way that on unmaximization/unsnapping the pointer
|
||||
* is still pointing at the appropriate half of the surface,
|
||||
/* Move window in such a way that on unmaximization/unsnapping the pointer
|
||||
* is still pointing at the appropriate half of the window,
|
||||
* with the same offset from the left or right edge. If the new
|
||||
* surface size is too small, and adding that offset puts the pointer
|
||||
* window size is too small, and adding that offset puts the pointer
|
||||
* into the other half or even beyond, move the pointer to the middle.
|
||||
*/
|
||||
if (!pointer_outside_of_surface && maximized)
|
||||
if (!pointer_outside_of_window && maximized)
|
||||
{
|
||||
WINDOWPLACEMENT placement;
|
||||
int unmax_width, unmax_height;
|
||||
int shadow_unmax_width, shadow_unmax_height;
|
||||
|
||||
placement.length = sizeof (placement);
|
||||
API_CALL (GetWindowPlacement, (GDK_SURFACE_HWND (surface), &placement));
|
||||
API_CALL (GetWindowPlacement, (GDK_SURFACE_HWND (window), &placement));
|
||||
|
||||
GDK_NOTE (MISC, g_print ("W32 WM unmaximized surface placement is %ld x %ld @ %ld : %ld\n",
|
||||
GDK_NOTE (MISC, g_print ("W32 WM unmaximized window placement is %ld x %ld @ %ld : %ld\n",
|
||||
placement.rcNormalPosition.right - placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.bottom - placement.rcNormalPosition.top,
|
||||
placement.rcNormalPosition.left,
|
||||
@@ -3555,9 +3587,9 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.top));
|
||||
|
||||
API_CALL (SetWindowPlacement, (GDK_SURFACE_HWND (surface), &placement));
|
||||
API_CALL (SetWindowPlacement, (GDK_SURFACE_HWND (window), &placement));
|
||||
}
|
||||
else if (!pointer_outside_of_surface && impl->snap_stash_int)
|
||||
else if (!pointer_outside_of_window && impl->snap_stash_int)
|
||||
{
|
||||
GdkRectangle new_pos;
|
||||
GdkRectangle snew_pos;
|
||||
@@ -3587,22 +3619,22 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
new_pos.y = root_y - new_pos.height / 2;
|
||||
}
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped surface to %d : %d\n",
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped window to %d : %d\n",
|
||||
new_pos.x, new_pos.y));
|
||||
discard_snapinfo (surface);
|
||||
gdk_win32_surface_move_resize (surface, new_pos.x, new_pos.y,
|
||||
discard_snapinfo (window);
|
||||
gdk_win32_surface_move_resize (window, new_pos.x, new_pos.y,
|
||||
new_pos.width, new_pos.height);
|
||||
}
|
||||
|
||||
|
||||
if (maximized)
|
||||
gdk_win32_surface_unmaximize (surface);
|
||||
gdk_win32_surface_unmaximize (window);
|
||||
else
|
||||
unsnap (surface, monitor);
|
||||
unsnap (window, monitor);
|
||||
|
||||
if (pointer_outside_of_surface)
|
||||
if (pointer_outside_of_window)
|
||||
{
|
||||
/* Pointer outside of the surface, move pointer into surface */
|
||||
/* Pointer outside of the window, move pointer into window */
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d is outside of %d x %d @ %d : %d, move it to %d : %d\n",
|
||||
root_x, root_y, wwidth, wheight, wx, wy, wx + wwidth / 2, wy + wheight / 2));
|
||||
root_x = wx + wwidth / 2;
|
||||
@@ -3615,29 +3647,26 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
if (restore_configure)
|
||||
impl->inhibit_configure = FALSE;
|
||||
|
||||
_gdk_win32_get_window_rect (surface, &rect);
|
||||
_gdk_win32_get_window_rect (window, &rect);
|
||||
|
||||
cursor_name = get_cursor_name_from_op (op, edge);
|
||||
|
||||
context->cursor = gdk_cursor_new_from_name (cursor_name, NULL);
|
||||
|
||||
pointer_surface = surface;
|
||||
pointer_window = window;
|
||||
|
||||
/* Note: This triggers a WM_CAPTURECHANGED, which will trigger
|
||||
* gdk_win32_surface_end_move_resize_drag(), which will end
|
||||
* our op before it even begins, but only if context->op is not NONE.
|
||||
* This is why we first do the grab, *then* set the op.
|
||||
*/
|
||||
gdk_device_grab (device, pointer_surface,
|
||||
gdk_device_grab (device, pointer_window,
|
||||
FALSE,
|
||||
GDK_ALL_EVENTS_MASK,
|
||||
context->cursor,
|
||||
timestamp);
|
||||
|
||||
context->window = g_object_ref (surface);
|
||||
context->window = g_object_ref (window);
|
||||
context->op = op;
|
||||
context->edge = edge;
|
||||
context->device = device;
|
||||
@@ -3657,10 +3686,10 @@ setup_drag_move_resize_context (GdkSurface *surface,
|
||||
calculate_aerosnap_regions (context);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("begin drag moveresize: surface %p, toplevel %p, "
|
||||
g_print ("begin drag moveresize: window %p, toplevel %p, "
|
||||
"op %u, edge %d, device %p, "
|
||||
"button %d, coord %d:%d, time %u\n",
|
||||
pointer_surface, surface,
|
||||
pointer_window, window,
|
||||
context->op, context->edge, context->device,
|
||||
context->button, context->start_root_x,
|
||||
context->start_root_y, context->timestamp));
|
||||
@@ -4055,61 +4084,45 @@ gdk_win32_surface_minimize (GdkSurface *window)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_maximize (GdkSurface *surface)
|
||||
gdk_win32_surface_maximize (GdkSurface *window)
|
||||
{
|
||||
GdkWin32Surface *impl;
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_maximize: %p: %s\n",
|
||||
GDK_SURFACE_HWND (surface),
|
||||
_gdk_win32_surface_state_to_string (surface->state)));
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
impl->inhibit_configure = TRUE;
|
||||
impl->force_recompute_size = FALSE;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (surface))
|
||||
GtkShowWindow (surface, SW_MAXIMIZE);
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_MAXIMIZE);
|
||||
else
|
||||
gdk_synthesize_surface_state (surface,
|
||||
gdk_synthesize_surface_state (window,
|
||||
0,
|
||||
GDK_TOPLEVEL_STATE_MAXIMIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_unmaximize (GdkSurface *surface)
|
||||
gdk_win32_surface_unmaximize (GdkSurface *window)
|
||||
{
|
||||
GdkWin32Surface *impl;
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_unmaximize: %p: %s\n",
|
||||
GDK_SURFACE_HWND (surface),
|
||||
_gdk_win32_surface_state_to_string (surface->state)));
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (surface);
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (window);
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (surface))
|
||||
GtkShowWindow (surface, SW_RESTORE);
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_RESTORE);
|
||||
else
|
||||
gdk_synthesize_surface_state (surface,
|
||||
gdk_synthesize_surface_state (window,
|
||||
GDK_TOPLEVEL_STATE_MAXIMIZED,
|
||||
0);
|
||||
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (impl->inhibit_configure)
|
||||
{
|
||||
impl->inhibit_configure = FALSE;
|
||||
impl->force_recompute_size = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4534,9 +4547,6 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
|
||||
&surface->x, &surface->y,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!impl->inhibit_configure)
|
||||
impl->force_recompute_size = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4551,18 +4561,8 @@ _gdk_win32_surface_compute_size (GdkSurface *surface)
|
||||
|
||||
if (!impl->drag_move_resize_context.native_move_resize_pending)
|
||||
{
|
||||
if (GDK_IS_TOPLEVEL (surface) && impl->force_recompute_size)
|
||||
{
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
impl->force_recompute_size = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
}
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
||||
@@ -337,7 +337,6 @@ struct _GdkWin32Surface
|
||||
int configured_height;
|
||||
RECT configured_rect;
|
||||
} next_layout;
|
||||
gboolean force_recompute_size;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
guint egl_force_redraw_all : 1;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# libwntab32x.la - a libtool library file
|
||||
# Generated by hand, compatible with libtool
|
||||
# Just a wrapper for libwntab32x.a, which is just a copy of wntab32x.lib
|
||||
#
|
||||
# The name that we can dlopen(3).
|
||||
dlname=''
|
||||
|
||||
# Names of this library.
|
||||
library_names=''
|
||||
|
||||
# The name of the static archive.
|
||||
old_library='libwntab32x.a'
|
||||
|
||||
# Libraries that this one depends upon.
|
||||
dependency_libs=''
|
||||
|
||||
# Version information
|
||||
current=0
|
||||
age=0
|
||||
revision=0
|
||||
|
||||
# Is this an already installed library?
|
||||
installed=no
|
||||
|
||||
# Files to dlopen/dlpreopen
|
||||
dlopen=''
|
||||
dlpreopen=''
|
||||
|
||||
# Directory that this library needs to be installed in:
|
||||
libdir=''
|
||||
@@ -19,8 +19,6 @@ gdk_win32_sources = files([
|
||||
'gdkhdataoutputstream-win32.c',
|
||||
'gdkinput-winpointer.c',
|
||||
'gdkkeys-win32.c',
|
||||
'gdkkeys-win32-impl.c',
|
||||
'gdkkeys-win32-impl-wow64.c',
|
||||
'gdkwin32langnotification.c',
|
||||
'gdkmain-win32.c',
|
||||
'gdkmonitor-win32.c',
|
||||
|
||||
@@ -1665,7 +1665,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
|
||||
direction,
|
||||
FALSE);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1799,7 +1799,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
|
||||
x, y,
|
||||
axes);
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1838,7 +1838,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
x = (double) xev->event_x / scale;
|
||||
y = (double) xev->event_y / scale;
|
||||
|
||||
|
||||
event = gdk_touch_event_new (ev->evtype == XI_TouchBegin
|
||||
? GDK_TOUCH_BEGIN
|
||||
: GDK_TOUCH_END,
|
||||
@@ -1946,7 +1946,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
y = (double) xev->event_y / scale;
|
||||
|
||||
event = gdk_touchpad_event_new_pinch (surface,
|
||||
NULL, /* FIXME make up sequences */
|
||||
device,
|
||||
xev->time,
|
||||
state,
|
||||
@@ -2007,7 +2006,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
y = (double) xev->event_y / scale;
|
||||
|
||||
event = gdk_touchpad_event_new_swipe (surface,
|
||||
NULL, /* FIXME make up sequences */
|
||||
device,
|
||||
xev->time,
|
||||
state,
|
||||
|
||||
@@ -71,8 +71,6 @@ gdk_x11_surface_destroy_glx_drawable (GdkX11Surface *self)
|
||||
if (self->glx_drawable == None)
|
||||
return;
|
||||
|
||||
gdk_gl_context_clear_current_if_surface (GDK_SURFACE (self));
|
||||
|
||||
glXDestroyWindow (gdk_x11_display_get_xdisplay (gdk_surface_get_display (GDK_SURFACE (self))),
|
||||
self->glx_drawable);
|
||||
|
||||
|
||||
@@ -3535,7 +3535,7 @@ gdk_x11_surface_unfullscreen (GdkSurface *surface)
|
||||
*
|
||||
* Returns the group this surface belongs to.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): The group of this surface;
|
||||
* Returns: (transfer none): The group of this surface;
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_x11_surface_get_group (GdkSurface *surface)
|
||||
|
||||
@@ -952,9 +952,9 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
guint program = 0;
|
||||
guint width = 0;
|
||||
guint height = 0;
|
||||
G_GNUC_UNUSED guint n_binds = 0;
|
||||
guint n_binds = 0;
|
||||
guint n_fbos = 0;
|
||||
G_GNUC_UNUSED guint n_uniforms = 0;
|
||||
guint n_uniforms = 0;
|
||||
guint n_programs = 0;
|
||||
guint vao_id;
|
||||
guint vbo_id;
|
||||
@@ -1396,7 +1396,7 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
|
||||
}
|
||||
else if (stride % bpp == 0 &&
|
||||
(gdk_gl_context_check_version (context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
|
||||
(!use_es || gdk_gl_context_check_version (context, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
|
||||
|
||||
|
||||
@@ -147,8 +147,7 @@ gsk_gl_compiler_new (GskGLDriver *driver,
|
||||
|
||||
gdk_gl_context_get_version (context, &maj, &min);
|
||||
|
||||
/* On Windows, legacy contexts can give us a GL 4.x context */
|
||||
if (maj >= 3)
|
||||
if (maj == 3)
|
||||
self->glsl_version = SHADER_VERSION_GL3_LEGACY;
|
||||
else
|
||||
self->glsl_version = SHADER_VERSION_GL2_LEGACY;
|
||||
|
||||
@@ -175,8 +175,8 @@ render_glyph (cairo_surface_t *surface,
|
||||
|
||||
glyph_info.glyph = key->glyph;
|
||||
glyph_info.geometry.width = value->ink_rect.width * 1024;
|
||||
glyph_info.geometry.x_offset = (0.25 * key->xshift - value->ink_rect.x) * 1024;
|
||||
glyph_info.geometry.y_offset = (0.25 * key->yshift - value->ink_rect.y) * 1024;
|
||||
glyph_info.geometry.x_offset = 0.25 * key->xshift - value->ink_rect.x * 1024;
|
||||
glyph_info.geometry.y_offset = 0.25 * key->yshift - value->ink_rect.y * 1024;
|
||||
|
||||
glyph_string.num_glyphs = 1;
|
||||
glyph_string.glyphs = &glyph_info;
|
||||
|
||||
@@ -4117,19 +4117,14 @@ gsk_gl_render_job_set_debug_fallback (GskGLRenderJob *job,
|
||||
}
|
||||
|
||||
static int
|
||||
get_framebuffer_format (GdkGLContext *context,
|
||||
guint framebuffer)
|
||||
get_framebuffer_format (guint framebuffer)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (!gdk_gl_context_check_version (context, 0, 0, 3, 0))
|
||||
return GL_RGBA8;
|
||||
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
||||
glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
|
||||
framebuffer ? GL_COLOR_ATTACHMENT0
|
||||
: gdk_gl_context_get_use_es (context) ? GL_BACK
|
||||
: GL_BACK_LEFT,
|
||||
: GL_BACK_LEFT,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &size);
|
||||
|
||||
if (size > 16)
|
||||
@@ -4166,7 +4161,7 @@ gsk_gl_render_job_new (GskGLDriver *driver,
|
||||
job->scale_x = scale_factor;
|
||||
job->scale_y = scale_factor;
|
||||
job->viewport = *viewport;
|
||||
job->target_format = get_framebuffer_format (job->command_queue->context, framebuffer);
|
||||
job->target_format = get_framebuffer_format (framebuffer);
|
||||
|
||||
gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, viewport, NULL);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user