Compare commits
15 Commits
content_fo
...
state-savi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9ce1959b4 | ||
|
|
a7edd0992e | ||
|
|
9f35250330 | ||
|
|
7e8dfd5bda | ||
|
|
aa0df60606 | ||
|
|
9ee07d3974 | ||
|
|
1f7ca109c9 | ||
|
|
bc2d8bfa33 | ||
|
|
ee0e82610c | ||
|
|
26c5240dcb | ||
|
|
ecf6c354b5 | ||
|
|
fd499188bd | ||
|
|
0c6fb610e6 | ||
|
|
1962f535e8 | ||
|
|
8db1b89ace |
@@ -24,8 +24,9 @@ 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:v32"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v31"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v31"
|
||||
|
||||
.only-default:
|
||||
only:
|
||||
@@ -59,7 +60,6 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
||||
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
paths:
|
||||
@@ -79,14 +79,9 @@ fedora-x86_64:
|
||||
script:
|
||||
- .gitlab-ci/show-info-linux.sh
|
||||
- meson subprojects update
|
||||
- mkdir _install
|
||||
- meson --prefix=${CI_PROJECT_DIR}/_install
|
||||
${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
_build
|
||||
- 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
|
||||
- meson compile -C _build_hello
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build broadway
|
||||
@@ -170,9 +165,6 @@ macos:
|
||||
- export MESON_FORCE_BACKTRACE=1
|
||||
script:
|
||||
- meson -Dx11-backend=false
|
||||
-Dbroadway-backend=true
|
||||
-Dmacos-backend=true
|
||||
-Dmedia-gstreamer=disabled
|
||||
-Dintrospection=disabled
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
@@ -310,7 +302,7 @@ asan-build:
|
||||
allow_failure: true
|
||||
|
||||
reference:
|
||||
image: $FEDORA_IMAGE
|
||||
image: $DOCS_IMAGE
|
||||
stage: docs
|
||||
needs: []
|
||||
variables:
|
||||
|
||||
@@ -38,6 +38,7 @@ RUN dnf -y install \
|
||||
gstreamer1-plugins-good \
|
||||
gstreamer1-plugins-bad-free-devel \
|
||||
gstreamer1-plugins-base-devel \
|
||||
gtk-doc \
|
||||
hicolor-icon-theme \
|
||||
iso-codes \
|
||||
itstool \
|
||||
|
||||
@@ -15,7 +15,7 @@ meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=enabled \
|
||||
-Dvulkan=yes \
|
||||
-Dprofiler=true \
|
||||
--werror \
|
||||
${EXTRA_MESON_FLAGS:-} \
|
||||
|
||||
@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson==0.56.2 || goto :error
|
||||
meson -Dmedia-gstreamer=disabled _build || goto :error
|
||||
meson _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
goto :EOF
|
||||
|
||||
210
NEWS
210
NEWS
@@ -1,213 +1,3 @@
|
||||
Overview of Changes in 4.3.2
|
||||
============================
|
||||
|
||||
* GtkToggleButton:
|
||||
- Fix the actionable implementation
|
||||
|
||||
* GtkCheckButton:
|
||||
- Fix the actionable implementation
|
||||
- Cancel activation on when the pointer leaves
|
||||
|
||||
* GtkMenuButton:
|
||||
- Make activatable again
|
||||
- Add a way to have an icon + arrow
|
||||
|
||||
* GtkColorButton:
|
||||
- Make activatable again
|
||||
|
||||
* GtkFontButton:
|
||||
- Make activatable again
|
||||
|
||||
* GtkAppChooserButton:
|
||||
- Make activatable again
|
||||
|
||||
* GtkColumnView:
|
||||
- Fix double activation
|
||||
|
||||
* GtkLabel:
|
||||
- Fix mnemonics without markup
|
||||
|
||||
* GtkTreeView:
|
||||
- Clip header buttons
|
||||
|
||||
* GtkTextView:
|
||||
- Add api to get the RTL and LTR contexts
|
||||
- Fix some errors in text history grouping
|
||||
|
||||
* GtkText:
|
||||
- Don't show placeholder text on top of entry text
|
||||
- Add api to compute the cursor extents
|
||||
- Fix y coordinates for text selection
|
||||
|
||||
* GtkFileChooser:
|
||||
- Don't show Trash in the side bar
|
||||
|
||||
* GtkPopoverMenu:
|
||||
- Add scrollbars to long menus
|
||||
|
||||
* GtkActionMuxer:
|
||||
- Fix propagation of accel changes
|
||||
|
||||
* Introspection:
|
||||
- Annotate all filename arguments
|
||||
- Rename GtkMediaStream apis to avoid name collisions
|
||||
- Rename GtkDropTarget properties to avoid name collisions
|
||||
- Make GtkPasswordEntryBuffer introspectable
|
||||
|
||||
* Printing:
|
||||
- Remove the Google Cloud Print backend
|
||||
|
||||
* Theme:
|
||||
- Sync included icons with the Adwaita icon theme
|
||||
|
||||
* GSK:
|
||||
- Avoid overflowing the vertex counter
|
||||
- Handle negative scales correctly in the ngl renderer
|
||||
|
||||
* GDK:
|
||||
- Cleanup and simplify OpenGL setup code
|
||||
- Add a GdkDisplay::init_gl vfunc and gdk_display_prepare_gl() api
|
||||
- Require EGL 1.4
|
||||
- Fix EGL + NVidia
|
||||
|
||||
* Build:
|
||||
- Enable gstreamer by default
|
||||
- Disable Vulkan by default
|
||||
- Remove the sassc option
|
||||
- Remove options and checks for X11 extensions
|
||||
|
||||
* X11:
|
||||
- Stop using XComposite
|
||||
- Remove the Visual cache
|
||||
|
||||
* Wayland:
|
||||
- Fix some DND corner cases
|
||||
- Work with version 2 of pointer-gestures-v1
|
||||
- Look for cursor themes in $HOME/.icons
|
||||
|
||||
* Windows:
|
||||
- Fix SIGILL on x64 due to popcnt
|
||||
- Fix popup placement
|
||||
- Fix drag icon placement
|
||||
- Clean up HiDPI and WGL support
|
||||
- Default to WGL
|
||||
|
||||
* MacOs:
|
||||
- Fix input method support
|
||||
- Register known clipboard types for drop targets
|
||||
- Add initial DND support
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
Portuguese
|
||||
Romanian
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.3.1
|
||||
============================
|
||||
|
||||
* GtkEmojiChooser:
|
||||
- Update data from CLDR 39
|
||||
- Load Emoji data for both language and territory
|
||||
|
||||
* GtkCalendar:
|
||||
- Fix an off-by-one error in day numbers
|
||||
|
||||
* GtkListView:
|
||||
- Add .activatable style class to activatable items
|
||||
|
||||
* GtkCheckButton:
|
||||
- Don't allow unchecking grouped radio buttons
|
||||
|
||||
*GtkToggleButton:
|
||||
- Fix mnemonic activation propagation
|
||||
|
||||
* GtkLabel:
|
||||
- Make mnemonics work even when invisible
|
||||
- Fix mnemonic activation propagation
|
||||
|
||||
* GtkMenuButton:
|
||||
- Add a property to mark primary menus and make F10 work
|
||||
|
||||
* GtkApplication:
|
||||
- Fix initial screensaver state async
|
||||
|
||||
* GtkEntry:
|
||||
- Apply xalign to placeholder text (as it was in GTK 3)
|
||||
|
||||
* GtkSpinButton:
|
||||
- Fix swipe gestures
|
||||
|
||||
* GtkStackSwitcher:
|
||||
- Implement GtkOrientable (as it was in GTK 3)
|
||||
- Fix a use-after-free problem with drag timeouts
|
||||
|
||||
* GtkFileChooser:
|
||||
- Add support for (case-insensitive) suffix matches in GtkFileFilter
|
||||
|
||||
* GtkPasswordEntry:
|
||||
- Make GtkPasswordEntryBuffer public, to make it easier
|
||||
to write your own password entry widget
|
||||
|
||||
* Input:
|
||||
- Fix interference between various obscure XKB features
|
||||
(e.g. overlays) and Compose sequences
|
||||
|
||||
* Action support:
|
||||
- Fix submenu-action handling
|
||||
|
||||
* Theme:
|
||||
- Update icons from the Adwaita icon theme
|
||||
- Fix icon names for GtkSwitch
|
||||
- Fix switch-off icon
|
||||
|
||||
* GSK:
|
||||
- Improve transformed offscreen rendering
|
||||
- Add padding between cached glyphs
|
||||
|
||||
* Wayland:
|
||||
- Fix monitor sizes in the presence of transforms
|
||||
- Add a getter for the EGLDisplay
|
||||
- Fix click-drag-release sequences for popovers
|
||||
|
||||
* X11:
|
||||
- Support EGL for X11. Fall back to GLX if EGL isn't available
|
||||
- Always fall back to GLX on NVidia
|
||||
- Add a getter for the EGLDisplay
|
||||
|
||||
* Broadway:
|
||||
- Add a setter for display scale
|
||||
|
||||
* Windows:
|
||||
- Add a getter for the EGLDisplay
|
||||
- Make GL work for media playback
|
||||
|
||||
* MacOS:
|
||||
- Fix menubar appearance
|
||||
|
||||
* Tools:
|
||||
- gtk4-builder-tool: Replace can-focus with focusable in 3-to-4 conversion
|
||||
|
||||
* Introspection:
|
||||
- Add missing annotations in a few places (e.g. gtk_free_view_row_activated)
|
||||
|
||||
* Build:
|
||||
- Only build one source file with -mf16c
|
||||
- Fix devel styling for ci flatpak builds
|
||||
- Generate appdata for demo flatpaks
|
||||
|
||||
* Docs:
|
||||
- Numerous fixes and additions
|
||||
|
||||
* Translation updates:
|
||||
Friulian
|
||||
Nepali
|
||||
Norwegian Bokmål
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.3.0
|
||||
============================
|
||||
|
||||
|
||||
@@ -157,8 +157,8 @@ Release notes
|
||||
The release notes for GTK are part of the migration guide in the API
|
||||
reference. See:
|
||||
|
||||
- [3.x release notes](https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html)
|
||||
- [4.x release notes](https://docs.gtk.org/gtk4/migrating-3to4.html)
|
||||
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
|
||||
- [4.x release notes](https://developer.gnome.org/gtk4/unstable/gtk-migrating-3-to-4.html)
|
||||
|
||||
Licensing terms
|
||||
---------------
|
||||
|
||||
@@ -124,6 +124,9 @@
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#mesondefine HAVE_UNISTD_H
|
||||
|
||||
/* Have the XCOMPOSITE X extension */
|
||||
#mesondefine HAVE_XCOMPOSITE
|
||||
|
||||
/* Have the Xcursor library */
|
||||
#mesondefine HAVE_XCURSOR
|
||||
|
||||
|
||||
@@ -163,8 +163,8 @@ drag_update_cb (GtkGestureDrag *drag,
|
||||
|
||||
static void
|
||||
drag_end_cb (GtkGestureDrag *drag,
|
||||
double dx,
|
||||
double dy,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
|
||||
|
||||
@@ -21,10 +21,8 @@ do_menu (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *scale;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
||||
@@ -33,23 +31,11 @@ do_menu (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), sw);
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||
gtk_box_append (GTK_BOX (box), scale);
|
||||
|
||||
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.Demo4</id>
|
||||
<launchable type="desktop-id">org.gtk.Demo4.desktop</launchable>
|
||||
<id>org.gtk.Demo4.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Demo</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<description>
|
||||
@@ -31,7 +30,6 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||
<description>
|
||||
|
||||
@@ -150,7 +150,7 @@ gtk_nuclear_media_stream_step (gpointer data)
|
||||
* call our pause function to pause the stream.
|
||||
*/
|
||||
if (nuclear->progress >= DURATION)
|
||||
gtk_media_stream_stream_ended (GTK_MEDIA_STREAM (nuclear));
|
||||
gtk_media_stream_ended (GTK_MEDIA_STREAM (nuclear));
|
||||
|
||||
/* The timeout function is removed by the pause function,
|
||||
* so we can just always return this value.
|
||||
@@ -267,11 +267,11 @@ gtk_nuclear_media_stream_init (GtkNuclearMediaStream *nuclear)
|
||||
* However, media streams need to tell GTK once they are initialized,
|
||||
* so we do that here.
|
||||
*/
|
||||
gtk_media_stream_stream_prepared (GTK_MEDIA_STREAM (nuclear),
|
||||
FALSE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
DURATION);
|
||||
gtk_media_stream_prepared (GTK_MEDIA_STREAM (nuclear),
|
||||
FALSE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
DURATION);
|
||||
}
|
||||
|
||||
/* And finally, we add the simple constructor we declared in the header. */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Peg Solitaire
|
||||
* #Keywords: GtkGridView, game
|
||||
*
|
||||
* This demo demonstrates how to use drag-and-drop to implement peg solitaire.
|
||||
* This demo demonstrates how to use drag'n'drop to implement peg solitaire.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -98,7 +98,7 @@ solitaire_peg_init (SolitairePeg *peg)
|
||||
|
||||
/* Add a little setter for the peg's position.
|
||||
* We want to track those so that we can check for legal moves
|
||||
* during drag-and-drop operations.
|
||||
* during drag'n'drop operations.
|
||||
*/
|
||||
static void
|
||||
solitaire_peg_set_position (SolitairePeg *peg,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.IconBrowser4</id>
|
||||
<launchable type="desktop-id">org.gtk.IconBrowser4.desktop</launchable>
|
||||
<id>org.gtk.IconBrowser4.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Icon Browser</name>
|
||||
<summary>Program to browse themed icons</summary>
|
||||
<description>
|
||||
@@ -30,7 +29,6 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||
<description>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.PrintEditor4</id>
|
||||
<launchable type="desktop-id">org.gtk.PrintEditor4.desktop</launchable>
|
||||
<id>org.gtk.PrintEditor4.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Print Editor</name>
|
||||
<summary>Program to demonstrate GTK printing</summary>
|
||||
<description>
|
||||
@@ -25,7 +24,6 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="3.99.0" date="2020-07-30">
|
||||
<description>
|
||||
|
||||
@@ -721,6 +721,7 @@ static const char ui_info[] =
|
||||
" <item>"
|
||||
" <attribute name='label'>_New</attribute>"
|
||||
" <attribute name='action'>app.new</attribute>"
|
||||
" <attribute name='accel'><Primary>n</attribute>"
|
||||
" </item>"
|
||||
" <item>"
|
||||
" <attribute name='label'>_Open</attribute>"
|
||||
@@ -729,10 +730,12 @@ static const char ui_info[] =
|
||||
" <item>"
|
||||
" <attribute name='label'>_Save</attribute>"
|
||||
" <attribute name='action'>app.save</attribute>"
|
||||
" <attribute name='accel'><Primary>s</attribute>"
|
||||
" </item>"
|
||||
" <item>"
|
||||
" <attribute name='label'>Save _As...</attribute>"
|
||||
" <attribute name='action'>app.save-as</attribute>"
|
||||
" <attribute name='accel'><Primary>s</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" <section>"
|
||||
@@ -753,6 +756,7 @@ static const char ui_info[] =
|
||||
" <item>"
|
||||
" <attribute name='label'>_Quit</attribute>"
|
||||
" <attribute name='action'>app.quit</attribute>"
|
||||
" <attribute name='accel'><Primary>q</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </submenu>"
|
||||
@@ -762,6 +766,7 @@ static const char ui_info[] =
|
||||
" <item>"
|
||||
" <attribute name='label'>_About Print Editor</attribute>"
|
||||
" <attribute name='action'>app.about</attribute>"
|
||||
" <attribute name='accel'><Primary>a</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </submenu>"
|
||||
@@ -789,15 +794,6 @@ startup (GApplication *app)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GMenuModel *menubar;
|
||||
struct {
|
||||
const char *action_and_target;
|
||||
const char *accelerators[2];
|
||||
} accels[] = {
|
||||
{ "app.new", { "<Control>n", NULL } },
|
||||
{ "app.quit", { "<Control>q", NULL } },
|
||||
{ "app.save", { "<Control>s", NULL } },
|
||||
{ "app.about", { "<Control>a", NULL } },
|
||||
};
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_string (builder, ui_info, -1, NULL);
|
||||
@@ -806,9 +802,6 @@ startup (GApplication *app)
|
||||
|
||||
gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
|
||||
|
||||
for (int i = 0; i < G_N_ELEMENTS (accels); i++)
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), accels[i].action_and_target, accels[i].accelerators);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.WidgetFactory4</id>
|
||||
<launchable type="desktop-id">org.gtk.WidgetFactory4.desktop</launchable>
|
||||
<id>org.gtk.WidgetFactory4.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Widget Factory</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<description>
|
||||
@@ -32,7 +31,6 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||
<description>
|
||||
|
||||
@@ -1997,7 +1997,6 @@ activate (GApplication *app)
|
||||
const char *accelerators[2];
|
||||
} accels[] = {
|
||||
{ "app.about", { "F1", NULL } },
|
||||
{ "app.shortcuts", { "<Control>question", NULL } },
|
||||
{ "app.quit", { "<Control>q", NULL } },
|
||||
{ "app.open-in", { "<Control>n", NULL } },
|
||||
{ "win.dark", { "<Control>d", NULL } },
|
||||
|
||||
@@ -2902,7 +2902,7 @@ bad things might happen.</property>
|
||||
|
||||
<action-widgets>
|
||||
<action-widget response="cancel">cancel_info_dialog</action-widget>
|
||||
<action-widget response="ok" default="true">doit_info_dialog</action-widget>
|
||||
<action-widget response="ok">doit_info_dialog</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkDialog" id="action_dialog">
|
||||
|
||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
license = "GPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0", "cairo-1.0", "Pango-1.0", "GdkWayland-4.0", "GdkX11-4.0" ]
|
||||
devhelp = true
|
||||
|
||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
license = "GPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0" ]
|
||||
devhelp = true
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
Title: Drag-and-Drop in GTK
|
||||
|
||||
Drag-and-Drop (DND) is a user interaction pattern where users drag a UI element
|
||||
from one place to another, either inside a single application or between
|
||||
different application windows.
|
||||
|
||||
When the element is 'dropped', data is transferred from the source to the
|
||||
destination, according to the drag action that is negotiated between both
|
||||
sides. Most commonly, that is a _copy_, but it can also be a _move_ or a
|
||||
_link_, depending on the kind of data and how the drag operation has been
|
||||
set up.
|
||||
|
||||
This chapter gives an overview over how Drag-and-Drop is handled with event
|
||||
controllers in GTK.
|
||||
|
||||
## Drag sources
|
||||
|
||||
To make data available via DND, you create a [class@Gtk.DragSource]. Drag sources
|
||||
are event controllers, which initiate a Drag-and-Drop operation when the user clicks
|
||||
and drags the widget.
|
||||
|
||||
A drag source can be set up ahead of time, with the desired drag action(s) and the data
|
||||
to be transferred. But it is also possible to provide the data when a drag operation
|
||||
is about to begin, by connecting to the [signal@Gtk.DragSource::prepare] signal.
|
||||
|
||||
The GtkDragSource emits the [signal@Gtk.DragSource::drag-begin] signal when the DND
|
||||
operation starts, and the [signal@Gtk.DragSource::drag-end] signal when it is done.
|
||||
But it is not normally necessary to handle these signals. One case in which a ::drag-end
|
||||
handler is necessary is to implement `GDK_ACTION_MOVE`.
|
||||
|
||||
## Drop targets
|
||||
|
||||
To receive data via DND, you create a [class@Gtk.DropTarget], and tell it what kind of
|
||||
data to accept. You need to connect to the [signal@Gtk.DropTarget::drop] signal to receive
|
||||
the data when a DND operation occurs.
|
||||
|
||||
While a DND operation is ongoing, GTK provides updates when the pointer moves over
|
||||
the widget to which the drop target is associated. The [signal@Gtk.DropTarget::enter],
|
||||
[signal@Gtk.DropTarget::leave] and [signal@Gtk.DropTarget::motion] signals get emitted
|
||||
for this purpose.
|
||||
|
||||
GtkDropTarget provides a simple API, and only provides the data when it has been completely
|
||||
transferred. If you need to handle the data transfer yourself (for example to provide progress
|
||||
information during the transfer), you can use the more complicated [class@Gtk.DropTargetAsync].
|
||||
|
||||
## Other considerations
|
||||
|
||||
It is sometimes necessary to update the UI of the destination while a DND operation is ongoing,
|
||||
say to scroll or expand a view, or to switch pages. Typically, such UI changes are triggered
|
||||
by hovering over the widget in question.
|
||||
|
||||
[class@Gtk.DropControllerMotion] is an event controller that can help with implementing such
|
||||
behaviors. It is very similar to [class@Gtk.EventControllerMotion], but provides events during
|
||||
a DND operation.
|
||||
@@ -161,19 +161,19 @@ activate (GtkApplication *app,
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *button;
|
||||
GtkWidget *box;
|
||||
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
|
||||
button = gtk_button_new_with_label ("Hello World");
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
button = gtk_button_new_with_label ("Hello World");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), button);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
@@ -46,8 +46,7 @@ display, unless specified otherwise.
|
||||
<para>
|
||||
<command>gtk4-launch</command> takes at least one argument, the name of
|
||||
the application to launch. The name should match application desktop file name,
|
||||
as residing in the applications subdirectories of the XDG data directories, with
|
||||
or without the '.desktop' suffix.
|
||||
as residing in /usr/share/application, with or without the '.desktop' suffix.
|
||||
</para>
|
||||
<para>
|
||||
If called with more than one argument, the rest of them besides the application
|
||||
@@ -72,14 +71,4 @@ application.
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Environment</title>
|
||||
<para>Some environment variables affect the behavior of <command>gtk4-launch</command>.</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>XDG_DATA_HOME</option>, <option>XDG_DATA_DIRS</option></term>
|
||||
<listitem><para>The environment variables specifying the XDG dta directories.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
license = "GPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0", "Gsk-4.0" ]
|
||||
devhelp = true
|
||||
@@ -57,7 +57,6 @@ content_files = [
|
||||
"initialization.md",
|
||||
"actions.md",
|
||||
"input-handling.md",
|
||||
"drag-and-drop.md",
|
||||
"drawing-model.md",
|
||||
"css-overview.md",
|
||||
"css-properties.md",
|
||||
|
||||
@@ -99,12 +99,6 @@ you should stop using `GdkVisual` APIs, since this object not longer
|
||||
exists in GTK 4. Most of its APIs are deprecated already and not
|
||||
useful when dealing with RGBA visuals.
|
||||
|
||||
### Stop using `gtk_widget_set_app_paintable`
|
||||
|
||||
This is gone in GTK4 with no direct replacement. But for some usecases there
|
||||
are alternatives. If you want to make the background transparent, you can set
|
||||
the background color to, for example, `rgba(255, 255, 255, 0)` using CSS instead.
|
||||
|
||||
### Stop using `GtkBox` padding, fill and expand child properties
|
||||
|
||||
GTK 4 removes these [class@Gtk.Box] child properties, so you should stop using
|
||||
@@ -139,7 +133,7 @@ or `gtk_style_context_get_color()` only accept the context's current
|
||||
state for their state argument. You should update all callers to pass
|
||||
the current state.
|
||||
|
||||
### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_window()`
|
||||
### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_surface()`
|
||||
|
||||
These functions are not supported in GTK 4. Instead, either use
|
||||
backend-specific APIs, or render your widgets using
|
||||
@@ -193,22 +187,11 @@ for this change.
|
||||
| ::grab-broken-event | - |
|
||||
|
||||
Event signals which are not directly related to input have to be dealt with
|
||||
on a one-by-one basis:
|
||||
|
||||
- If you were using `::configure-event` and `::window-state-event` to save
|
||||
window state, you should use property notification for corresponding
|
||||
[class@Gtk.Window] properties, such as [property@Gtk.Window:default-width],
|
||||
[property@Gtk.Window:default-height], [property@Gtk.Window:maximized] or
|
||||
[property@Gtk.Window:fullscreened].
|
||||
- If you were using `::delete-event` to present a confirmation when using
|
||||
the close button of a window, you should use the
|
||||
[signal@Gtk.Window::close-request] signal.
|
||||
- If you were using `::map-event` and `::unmap-event` to track a window
|
||||
being mapped, you should use property notification for the
|
||||
[property@Gdk.Surface:mapped] property instead.
|
||||
- The `::damage-event` signal has no replacement, as the only consumer
|
||||
of damage events were the offscreen GDK surfaces, which have no
|
||||
replacement in GTK 4.x.
|
||||
on a one-by-one basis. If you were using `::configure-event` and
|
||||
`::window-state-event` to save window state, you should use property
|
||||
notification for corresponding [class@Gtk.Window] properties, such as
|
||||
[property@Gtk.Window:default-width], [property@Gtk.Window:default-height],
|
||||
[property@Gtk.Window:maximized] or [property@Gtk.Window:fullscreened].
|
||||
|
||||
### Set a proper application ID
|
||||
|
||||
@@ -249,10 +232,6 @@ in GTK 3, you can prepare for the switch by using `gtk_widget_destroy()`
|
||||
only on toplevel windows, and replace all other uses with
|
||||
`gtk_container_remove()` or `g_object_unref()`.
|
||||
|
||||
### Stop using the GtkWidget.destroy vfunc
|
||||
|
||||
Instead of implementing GtkWidget.destroy, you can implement GObject.dispose.
|
||||
|
||||
### Reduce the use of generic container APIs
|
||||
|
||||
GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there
|
||||
@@ -625,9 +604,6 @@ from `FALSE` to `TRUE`. In addition, there is a [property@Gtk.Widget:focusable]
|
||||
property, which controls whether an individual widget can receive
|
||||
the input focus.
|
||||
|
||||
The `gtk4-builder-tool` utility, when called with the `--3to4` option of the
|
||||
`simplify` command, will replace `:can-focus` by `:focusable`.
|
||||
|
||||
The feature to automatically keep the focus widget scrolled into view with
|
||||
`gtk_container_set_focus_vadjustment()` has been removed together with
|
||||
`GtkContainer`, and is provided by scrollable widgets instead. In the common
|
||||
@@ -764,7 +740,7 @@ The abstract base class `GtkBin` for single-child containers has been
|
||||
removed. The former subclasses are now derived directly from `GtkWidget`,
|
||||
and have a "child" property for their child widget. To add a child, use
|
||||
the setter for the "child" property (e.g. [method@Gtk.Frame.set_child]) instead
|
||||
of `gtk_container_add()`. Adding a child in a ui file with `<child>` still works.
|
||||
of `gtk_container_add()`. Adding a child in a ui file with <child> still works.
|
||||
|
||||
The affected classes are:
|
||||
|
||||
@@ -790,7 +766,7 @@ expand flags) and [vfunc@Gtk.Widget.get_request_mode] (if you want your
|
||||
container to support height-for-width).
|
||||
|
||||
You may also want to implement the [iface@Gtk.Buildable] interface, to support
|
||||
adding children with `<child>` in ui files.
|
||||
adding children with <child> in ui files.
|
||||
|
||||
### Adapt to GtkContainer removal
|
||||
|
||||
@@ -801,7 +777,7 @@ and have class-specific add() and remove() functions.
|
||||
The most noticeable change is the use of [method@Gtk.Box.append] or [method@Gtk.Box.prepend]
|
||||
instead of `gtk_container_add()` for adding children to `GtkBox`, and the change
|
||||
to use container-specific remove functions, such as [method@Gtk.Stack.remove] instead
|
||||
of `gtk_container_remove()`. Adding a child in a ui file with `<child>` still works.
|
||||
of `gtk_container_remove()`. Adding a child in a ui file with <child> still works.
|
||||
|
||||
The affected classes are:
|
||||
|
||||
@@ -828,11 +804,6 @@ by a layout manager (if they are layout-related), or handled in some
|
||||
other way. One possibility is to use child meta objects, as seen with
|
||||
[class@Gtk.AssistantPage], [class@Gtk.StackPage] and the like.
|
||||
|
||||
If you used to define child properties with `<packing>` in ui files, you have
|
||||
to switch to using `<layout>` for the corresponding layout properties.
|
||||
`gtk4-builder-tool` can help with this conversion, with the `--3to4` option
|
||||
of the `simplify` command.
|
||||
|
||||
The replacements for gtk_container_add() are:
|
||||
|
||||
| Widget | Replacement |
|
||||
@@ -1359,4 +1330,3 @@ of tree models, and widgets instead of cell renderers.
|
||||
|
||||
To learn more about the new list widgets, you can read the [List Widget
|
||||
Overview](#ListWidget).
|
||||
|
||||
|
||||
@@ -59,12 +59,14 @@ example_app_startup (GApplication *app)
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_activate (GApplication *app)
|
||||
example_app_create_window (GtkApplication *app,
|
||||
const char *save_id)
|
||||
{
|
||||
ExampleAppWindow *win;
|
||||
|
||||
win = example_app_window_new (EXAMPLE_APP (app));
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
gtk_widget_set_save_id (GTK_WIDGET (win), save_id);
|
||||
/* FIXME: differentiate save ids */
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -93,8 +95,8 @@ static void
|
||||
example_app_class_init (ExampleAppClass *class)
|
||||
{
|
||||
G_APPLICATION_CLASS (class)->startup = example_app_startup;
|
||||
G_APPLICATION_CLASS (class)->activate = example_app_activate;
|
||||
G_APPLICATION_CLASS (class)->open = example_app_open;
|
||||
GTK_APPLICATION_CLASS (class)->create_window = example_app_create_window;
|
||||
}
|
||||
|
||||
ExampleApp *
|
||||
@@ -103,5 +105,7 @@ example_app_new (void)
|
||||
return g_object_new (EXAMPLE_APP_TYPE,
|
||||
"application-id", "org.gtk.exampleapp",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
"register-session", TRUE,
|
||||
"save-state", TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ struct _ExampleAppWindow
|
||||
GtkWidget *words;
|
||||
GtkWidget *lines;
|
||||
GtkWidget *lines_label;
|
||||
|
||||
GList *files;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||
@@ -211,14 +213,68 @@ example_app_window_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&win->settings);
|
||||
|
||||
g_list_free_full (win->files, g_object_unref);
|
||||
win->files = NULL;
|
||||
|
||||
G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
example_app_window_save_state (GtkWidget *widget,
|
||||
GVariantDict *dict,
|
||||
gboolean *save_children)
|
||||
{
|
||||
ExampleAppWindow *win = EXAMPLE_APP_WINDOW (widget);
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
|
||||
for (GList *l = win->files; l; l = l->next)
|
||||
{
|
||||
g_variant_builder_add (&builder, "s", g_file_peek_path (G_FILE (l->data)));
|
||||
}
|
||||
|
||||
g_variant_dict_insert_value (dict, "files", g_variant_builder_end (&builder));
|
||||
|
||||
/* Save window state */
|
||||
GTK_WIDGET_CLASS (example_app_window_parent_class)->save_state (widget, dict, save_children);
|
||||
|
||||
*save_children = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
example_app_window_restore_state (GtkWidget *widget,
|
||||
GVariant *state)
|
||||
{
|
||||
ExampleAppWindow *win = EXAMPLE_APP_WINDOW (widget);
|
||||
GVariantIter *iter;
|
||||
|
||||
/* Restore window state */
|
||||
GTK_WIDGET_CLASS (example_app_window_parent_class)->restore_state (widget, state);
|
||||
|
||||
if (g_variant_lookup (state, "files", "as", &iter))
|
||||
{
|
||||
const char *path;
|
||||
|
||||
while (g_variant_iter_next (iter, "&s", &path))
|
||||
{
|
||||
GFile *file = g_file_new_for_path (path);
|
||||
example_app_window_open (win, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
example_app_window_class_init (ExampleAppWindowClass *class)
|
||||
{
|
||||
G_OBJECT_CLASS (class)->dispose = example_app_window_dispose;
|
||||
|
||||
GTK_WIDGET_CLASS (class)->save_state = example_app_window_save_state;
|
||||
GTK_WIDGET_CLASS (class)->restore_state = example_app_window_restore_state;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/exampleapp/window.ui");
|
||||
|
||||
@@ -288,4 +344,6 @@ example_app_window_open (ExampleAppWindow *win,
|
||||
|
||||
update_words (win);
|
||||
update_lines (win);
|
||||
|
||||
win->files = g_list_append (win->files, g_object_ref (file));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<property name="title" translatable="yes">Example Application</property>
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">400</property>
|
||||
<property name="save-id">window</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<child>
|
||||
@@ -26,6 +27,7 @@
|
||||
<object class="GtkToggleButton" id="search">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">edit-find-symbolic</property>
|
||||
<property name="save-id">search</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
@@ -38,6 +40,7 @@
|
||||
<child>
|
||||
<object class="GtkBox" id="content_box">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="save-id">content_box</property>
|
||||
<child>
|
||||
<object class="GtkSearchBar" id="searchbar">
|
||||
<child>
|
||||
@@ -49,8 +52,10 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox">
|
||||
<property name="save-id">hbox</property>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="sidebar">
|
||||
<property name="save-id">sidebar</property>
|
||||
<property name="transition-type">slide-right</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="sidebar-sw">
|
||||
@@ -66,6 +71,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="save-id">stack</property>
|
||||
<signal name="notify::visible-child" handler="visible_child_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -197,17 +197,6 @@ text_buffer_changed_cb (GtkTextBuffer *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fullscreen_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (gtk_window_is_fullscreen (GTK_WINDOW (object)))
|
||||
gtk_button_set_icon_name (GTK_BUTTON (user_data), "view-restore-symbolic");
|
||||
else
|
||||
gtk_button_set_icon_name (GTK_BUTTON (user_data), "view-fullscreen-symbolic");
|
||||
}
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "copy", window_copy, NULL, NULL, NULL },
|
||||
{ "paste", window_paste, NULL, NULL, NULL },
|
||||
@@ -225,18 +214,17 @@ new_window (GApplication *app,
|
||||
GtkWidget *window, *grid, *scrolled, *view;
|
||||
GtkWidget *toolbar;
|
||||
GtkWidget *button;
|
||||
GtkWidget *sw, *box, *label;
|
||||
|
||||
window = gtk_application_window_new (GTK_APPLICATION (app));
|
||||
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (window), win_entries, G_N_ELEMENTS (win_entries), window);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Bloatpad");
|
||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), TRUE);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), grid);
|
||||
|
||||
toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_add_css_class (toolbar, "toolbar");
|
||||
button = gtk_toggle_button_new ();
|
||||
gtk_button_set_icon_name (GTK_BUTTON (button), "format-justify-left");
|
||||
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::left");
|
||||
@@ -252,18 +240,21 @@ new_window (GApplication *app,
|
||||
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::right");
|
||||
gtk_box_append (GTK_BOX (toolbar), button);
|
||||
|
||||
button = gtk_toggle_button_new ();
|
||||
gtk_button_set_icon_name (GTK_BUTTON (button), "view-fullscreen-symbolic");
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.fullscreen");
|
||||
gtk_box_append (GTK_BOX (toolbar), button);
|
||||
g_signal_connect (window, "notify::fullscreened", G_CALLBACK (fullscreen_changed), button);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
gtk_widget_set_halign (box, GTK_ALIGN_END);
|
||||
label = gtk_label_new ("Fullscreen:");
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
sw = gtk_switch_new ();
|
||||
gtk_widget_set_valign (sw, GTK_ALIGN_CENTER);
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (sw), "win.fullscreen");
|
||||
gtk_box_append (GTK_BOX (box), sw);
|
||||
gtk_box_append (GTK_BOX (toolbar), box);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
|
||||
|
||||
scrolled = gtk_scrolled_window_new ();
|
||||
gtk_widget_set_hexpand (scrolled, TRUE);
|
||||
gtk_widget_set_vexpand (scrolled, TRUE);
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (scrolled), TRUE);
|
||||
view = gtk_text_view_new ();
|
||||
|
||||
g_object_set_data ((GObject*)window, "bloatpad-text", view);
|
||||
@@ -353,7 +344,6 @@ static void
|
||||
combo_changed (GtkComboBox *combo,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkDialog *dialog = user_data;
|
||||
GtkEntry *entry = g_object_get_data (user_data, "entry");
|
||||
const char *action;
|
||||
char **accels;
|
||||
@@ -369,17 +359,6 @@ combo_changed (GtkComboBox *combo,
|
||||
g_strfreev (accels);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), str);
|
||||
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
entry_changed (GtkEntry *entry,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkDialog *dialog = user_data;
|
||||
|
||||
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -393,7 +372,7 @@ response (GtkDialog *dialog,
|
||||
const char *str;
|
||||
char **accels;
|
||||
|
||||
if (response_id == GTK_RESPONSE_CANCEL)
|
||||
if (response_id == GTK_RESPONSE_CLOSE)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
return;
|
||||
@@ -409,8 +388,6 @@ response (GtkDialog *dialog,
|
||||
|
||||
gtk_application_set_accels_for_action (gtk_window_get_application (user_data), action, (const char **) accels);
|
||||
g_strfreev (accels);
|
||||
|
||||
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -425,41 +402,22 @@ edit_accels (GSimpleAction *action,
|
||||
GtkWidget *dialog;
|
||||
int i;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("Accelerators",
|
||||
NULL,
|
||||
GTK_DIALOG_USE_HEADER_BAR,
|
||||
"Close", GTK_RESPONSE_CANCEL,
|
||||
"Set", GTK_RESPONSE_APPLY,
|
||||
NULL);
|
||||
|
||||
dialog = gtk_dialog_new ();
|
||||
gtk_window_set_application (GTK_WINDOW (dialog), app);
|
||||
actions = gtk_application_list_action_descriptions (app);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
g_object_set (gtk_dialog_get_content_area (GTK_DIALOG (dialog)),
|
||||
"margin-top", 10,
|
||||
"margin-bottom", 10,
|
||||
"margin-start", 10,
|
||||
"margin-end", 10,
|
||||
"spacing", 10,
|
||||
NULL);
|
||||
|
||||
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), combo);
|
||||
for (i = 0; actions[i]; i++)
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), actions[i], actions[i]);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (combo_changed), dialog);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_widget_set_hexpand (entry, TRUE);
|
||||
g_signal_connect (entry, "notify::text", G_CALLBACK (entry_changed), dialog);
|
||||
|
||||
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), entry);
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), "Close", GTK_RESPONSE_CLOSE);
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), "Set", GTK_RESPONSE_APPLY);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (response), dialog);
|
||||
g_object_set_data (G_OBJECT (dialog), "combo", combo);
|
||||
g_object_set_data (G_OBJECT (dialog), "entry", entry);
|
||||
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
@@ -578,7 +536,7 @@ bloat_pad_startup (GApplication *application)
|
||||
|
||||
menu = gtk_application_get_menu_by_id (GTK_APPLICATION (application), "icon-menu");
|
||||
|
||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/insert-image.png");
|
||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/gtk-select-color.png");
|
||||
icon = g_file_icon_new (file);
|
||||
item = g_menu_item_new ("File Icon", NULL);
|
||||
g_menu_item_set_icon (item, icon);
|
||||
@@ -594,7 +552,7 @@ bloat_pad_startup (GApplication *application)
|
||||
g_object_unref (item);
|
||||
g_object_unref (icon);
|
||||
|
||||
bytes = g_resources_lookup_data ("/org/gtk/libgtk/icons/16x16/actions/media-eject.png", 0, NULL);
|
||||
bytes = g_resources_lookup_data ("/org/gtk/libgtk/icons/16x16/actions/gtk-select-font.png", 0, NULL);
|
||||
icon = g_bytes_icon_new (bytes);
|
||||
item = g_menu_item_new ("Bytes Icon", NULL);
|
||||
g_menu_item_set_icon (item, icon);
|
||||
@@ -603,19 +561,19 @@ bloat_pad_startup (GApplication *application)
|
||||
g_object_unref (icon);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
icon = G_ICON (gdk_pixbuf_new_from_resource ("/org/gtk/libgtk/icons/16x16/actions/folder-new.png", NULL));
|
||||
icon = G_ICON (gdk_pixbuf_new_from_resource ("/org/gtk/libgtk/icons/16x16/actions/gtk-preferences.png", NULL));
|
||||
item = g_menu_item_new ("Pixbuf", NULL);
|
||||
g_menu_item_set_icon (item, icon);
|
||||
g_menu_append_item (menu, item);
|
||||
g_object_unref (item);
|
||||
g_object_unref (icon);
|
||||
|
||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/bookmark-new.png");
|
||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/gtk-page-setup.png");
|
||||
icon = g_file_icon_new (file);
|
||||
emblem = g_emblem_new (icon);
|
||||
g_object_unref (icon);
|
||||
g_object_unref (file);
|
||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/dialog-warning.png");
|
||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/gtk-orientation-reverse-portrait.png");
|
||||
icon2 = g_file_icon_new (file);
|
||||
icon = g_emblemed_icon_new (icon2, emblem);
|
||||
item = g_menu_item_new ("Emblemed Icon", NULL);
|
||||
|
||||
@@ -4,10 +4,5 @@
|
||||
<gresource prefix="/org/gtk/bloatpad">
|
||||
<file preprocess="xml-stripblanks">gtk/menus.ui</file>
|
||||
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
||||
<file>icons/16x16/actions/format-justify-center-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/format-justify-left-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/format-justify-right-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-restore-symbolic.symbolic.png</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 119 B |
Binary file not shown.
|
Before Width: | Height: | Size: 115 B |
Binary file not shown.
|
Before Width: | Height: | Size: 117 B |
Binary file not shown.
|
Before Width: | Height: | Size: 207 B |
Binary file not shown.
|
Before Width: | Height: | Size: 204 B |
@@ -132,6 +132,7 @@ activate (GtkApplication *app,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *drawing_area;
|
||||
GtkGesture *drag;
|
||||
GtkGesture *press;
|
||||
@@ -141,11 +142,14 @@ activate (GtkApplication *app,
|
||||
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_window_set_child (GTK_WINDOW (window), frame);
|
||||
|
||||
drawing_area = gtk_drawing_area_new ();
|
||||
/* set a minimum size */
|
||||
gtk_widget_set_size_request (drawing_area, 100, 100);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), drawing_area);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), drawing_area);
|
||||
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw_cb, NULL, NULL);
|
||||
|
||||
|
||||
@@ -13,19 +13,19 @@ activate (GtkApplication *app,
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *button;
|
||||
GtkWidget *box;
|
||||
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
|
||||
button = gtk_button_new_with_label ("Hello World");
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
button = gtk_button_new_with_label ("Hello World");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), button);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
project('hello', 'c',
|
||||
version: '4.3.0',
|
||||
meson_version: '>= 0.50.0',
|
||||
)
|
||||
|
||||
executable('hello',
|
||||
[ 'hello-world.c' ],
|
||||
dependencies: [ dependency('gtk4') ],
|
||||
install: false
|
||||
)
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env -S GI_TYPELIB_PATH=${PWD}/build/gtk:${GI_TYPELIB_PATH} LD_PRELOAD=${LD_PRELOAD}:${PWD}/build/gtk/libgtk-4.so gjs
|
||||
|
||||
imports.gi.versions['Gtk'] = '4.0';
|
||||
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
|
||||
const DemoWidget = GObject.registerClass({
|
||||
GTypeName: 'DemoWidget',
|
||||
}, class DemoWidget extends Gtk.Widget {
|
||||
|
||||
_init(params = {}) {
|
||||
super._init(params);
|
||||
|
||||
let layout_manager = new Gtk.GridLayout ();
|
||||
this.set_layout_manager (layout_manager);
|
||||
this.label1 = new Gtk.Label({ label: "Red",
|
||||
hexpand: true,
|
||||
vexpand: true });
|
||||
this.label1.set_parent (this);
|
||||
let child1 = layout_manager.get_layout_child (this.label1);
|
||||
child1.set_row (0);
|
||||
child1.set_column (0);
|
||||
|
||||
this.label2 = new Gtk.Label({ label: "Green",
|
||||
hexpand: true,
|
||||
vexpand: true });
|
||||
this.label2.set_parent (this);
|
||||
let child2 = layout_manager.get_layout_child (this.label2);
|
||||
child2.set_row (0);
|
||||
child2.set_column (1);
|
||||
}
|
||||
});
|
||||
|
||||
// Create a new application
|
||||
let app = new Gtk.Application({ application_id: 'org.gtk.exampleapp' });
|
||||
|
||||
// When the application is launched…
|
||||
app.connect('activate', () => {
|
||||
// … create a new window …
|
||||
let win = new Gtk.ApplicationWindow({ application: app });
|
||||
// … with a button in it …
|
||||
let widget = new DemoWidget();
|
||||
win.set_child(widget);
|
||||
win.present();
|
||||
});
|
||||
|
||||
// Run the application
|
||||
app.run([]);
|
||||
|
||||
@@ -2,6 +2,7 @@ examples = [
|
||||
'builder',
|
||||
'drawing',
|
||||
'grid-packing',
|
||||
'hello-world',
|
||||
'plugman',
|
||||
'search-bar',
|
||||
'sunny',
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/usr/bin/env -S GI_TYPELIB_PATH=${PWD}/build/gtk:${GI_TYPELIB_PATH} LD_PRELOAD=${LD_PRELOAD}:${PWD}/build/gtk/libgtk-4.so python3
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version('Gdk', '4.0')
|
||||
gi.require_version('Gtk', '4.0')
|
||||
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Graphene
|
||||
|
||||
|
||||
class DemoWidget(Gtk.Widget):
|
||||
|
||||
__gtype_name__ = "DemoWidget"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def do_measure(self, orientation, for_size: int):
|
||||
# We need some space to draw
|
||||
return 100, 200, -1, -1
|
||||
|
||||
def do_snapshot(self, snapshot):
|
||||
# Draw four color squares
|
||||
color = Gdk.RGBA()
|
||||
rect = Graphene.Rect.alloc()
|
||||
|
||||
width = self.get_width() / 2
|
||||
height = self.get_height() / 2
|
||||
|
||||
Gdk.RGBA.parse(color, "red")
|
||||
rect.init(0, 0, width, height)
|
||||
snapshot.append_color(color, rect)
|
||||
|
||||
Gdk.RGBA.parse(color, "green")
|
||||
rect.init(width, 0, width, height)
|
||||
snapshot.append_color(color, rect)
|
||||
|
||||
Gdk.RGBA.parse(color, "yellow")
|
||||
rect.init(0, height, width, height)
|
||||
snapshot.append_color(color, rect)
|
||||
|
||||
Gdk.RGBA.parse(color, "blue")
|
||||
rect.init(width, height, width, height)
|
||||
snapshot.append_color(color, rect)
|
||||
|
||||
def on_activate(app):
|
||||
# Create a new window
|
||||
win = Gtk.ApplicationWindow(application=app)
|
||||
win.set_title("Squares")
|
||||
icon = DemoWidget()
|
||||
win.set_child(icon)
|
||||
win.present()
|
||||
|
||||
# Create a new application
|
||||
app = Gtk.Application(application_id='org.gtk.exampleapp')
|
||||
app.connect('activate', on_activate)
|
||||
|
||||
# Run the application
|
||||
app.run(None)
|
||||
@@ -12,7 +12,7 @@ new_window (GApplication *app,
|
||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), TRUE);
|
||||
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Sunny");
|
||||
gtk_window_set_icon_name (GTK_WINDOW (window), "weather-clear-symbolic");
|
||||
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
@@ -78,7 +78,7 @@ show_about (GSimpleAction *action,
|
||||
gtk_show_about_dialog (NULL,
|
||||
"program-name", "Sunny",
|
||||
"title", "About Sunny",
|
||||
"logo-icon-name", "weather-clear-symbolic",
|
||||
"logo-icon-name", "sunny",
|
||||
"comments", "A cheap Bloatpad clone.",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -48,8 +48,6 @@ void gdk_broadway_display_show_keyboard (GdkBroadwayDis
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_broadway_display_hide_keyboard (GdkBroadwayDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
int gdk_broadway_display_get_surface_scale (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
void gdk_broadway_display_set_surface_scale (GdkDisplay *display,
|
||||
int scale);
|
||||
|
||||
@@ -361,29 +361,6 @@ gdk_broadway_display_set_surface_scale (GdkDisplay *display,
|
||||
gdk_monitor_set_scale_factor (self->monitor, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_broadway_display_get_surface_scale:
|
||||
* @display: (type GdkBroadwayDisplay): the display
|
||||
*
|
||||
* Gets the surface scale that was previously set by the client or
|
||||
* gdk_broadway_display_set_surface_scale().
|
||||
*
|
||||
* Returns: the scale for surfaces
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
int
|
||||
gdk_broadway_display_get_surface_scale (GdkDisplay *display)
|
||||
{
|
||||
GdkBroadwayDisplay *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_BROADWAY_DISPLAY (display), 1);
|
||||
|
||||
self = GDK_BROADWAY_DISPLAY (display);
|
||||
|
||||
return self->scale_factor;
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
gdk_broadway_display_get_monitors (GdkDisplay *display)
|
||||
{
|
||||
|
||||
@@ -127,9 +127,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context" },
|
||||
{ "gl-gles", GDK_DEBUG_GL_GLES, "Use a GLES OpenGL context" },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
|
||||
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows" },
|
||||
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11" },
|
||||
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows" },
|
||||
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
|
||||
@@ -332,13 +330,14 @@ gdk_display_open_default (void)
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_get_startup_notification_id:
|
||||
*
|
||||
* gdk_get_startup_notification_id
|
||||
*
|
||||
* Returns the original value of the DESKTOP_STARTUP_ID environment
|
||||
* variable if it was defined and valid, or %NULL otherwise.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the original value of the
|
||||
* DESKTOP_STARTUP_ID environment variable
|
||||
* DESKTOP_STARTUP_ID environment variable, or %NULL.
|
||||
*/
|
||||
const char *
|
||||
gdk_get_startup_notification_id (void)
|
||||
|
||||
@@ -340,7 +340,7 @@ gdk_cursor_new_from_name (const char *name,
|
||||
* @texture: the texture providing the pixel data
|
||||
* @hotspot_x: the horizontal offset of the “hotspot” of the cursor
|
||||
* @hotspot_y: the vertical offset of the “hotspot” of the cursor
|
||||
* @fallback: (nullable): the `GdkCursor` to fall back to when
|
||||
* @fallback: (nullable): %NULL or the `GdkCursor` to fall back to when
|
||||
* this one cannot be supported
|
||||
*
|
||||
* Creates a new cursor from a `GdkTexture`.
|
||||
|
||||
@@ -41,12 +41,10 @@ typedef enum {
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 15,
|
||||
GDK_DEBUG_GL_GLES = 1 << 16,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 17,
|
||||
GDK_DEBUG_GL_EGL = 1 << 18,
|
||||
GDK_DEBUG_GL_GLX = 1 << 19,
|
||||
GDK_DEBUG_GL_WGL = 1 << 20,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 21,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 22,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 23,
|
||||
GDK_DEBUG_GL_GLX = 1 << 18,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 19,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 20,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 21
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
|
||||
218
gdk/gdkdisplay.c
218
gdk/gdkdisplay.c
@@ -77,23 +77,6 @@ enum {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
typedef struct _GdkDisplayPrivate GdkDisplayPrivate;
|
||||
|
||||
struct _GdkDisplayPrivate {
|
||||
/* The base context that all other contexts inherit from.
|
||||
* This context is never exposed to public API and is
|
||||
* allowed to have a %NULL surface.
|
||||
*/
|
||||
GdkGLContext *gl_context;
|
||||
GError *gl_error;
|
||||
|
||||
guint rgba : 1;
|
||||
guint composited : 1;
|
||||
guint input_shapes : 1;
|
||||
|
||||
GdkDebugFlags debug_flags;
|
||||
};
|
||||
|
||||
static void gdk_display_dispose (GObject *object);
|
||||
static void gdk_display_finalize (GObject *object);
|
||||
|
||||
@@ -102,7 +85,7 @@ static GdkAppLaunchContext *gdk_display_real_get_app_launch_context (GdkDisplay
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_display_get_property (GObject *object,
|
||||
@@ -136,14 +119,10 @@ gdk_display_real_make_default (GdkDisplay *display)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkGLContext *
|
||||
gdk_display_default_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
static void
|
||||
gdk_display_real_opened (GdkDisplay *display)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("The current backend does not support OpenGL"));
|
||||
|
||||
return NULL;
|
||||
_gdk_display_manager_add_display (gdk_display_manager_get (), display);
|
||||
}
|
||||
|
||||
static GdkSeat *
|
||||
@@ -155,12 +134,6 @@ gdk_display_real_get_default_seat (GdkDisplay *display)
|
||||
return display->seats->data;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_real_opened (GdkDisplay *display)
|
||||
{
|
||||
_gdk_display_manager_add_display (gdk_display_manager_get (), display);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_class_init (GdkDisplayClass *class)
|
||||
{
|
||||
@@ -170,11 +143,10 @@ gdk_display_class_init (GdkDisplayClass *class)
|
||||
object_class->dispose = gdk_display_dispose;
|
||||
object_class->get_property = gdk_display_get_property;
|
||||
|
||||
class->make_default = gdk_display_real_make_default;
|
||||
class->get_app_launch_context = gdk_display_real_get_app_launch_context;
|
||||
class->init_gl = gdk_display_default_init_gl;
|
||||
class->get_default_seat = gdk_display_real_get_default_seat;
|
||||
class->opened = gdk_display_real_opened;
|
||||
class->make_default = gdk_display_real_make_default;
|
||||
class->get_default_seat = gdk_display_real_get_default_seat;
|
||||
|
||||
/**
|
||||
* GdkDisplay:composited: (attributes org.gtk.Property.get=gdk_display_is_composited)
|
||||
@@ -322,8 +294,6 @@ free_device_grabs_foreach (gpointer key,
|
||||
static void
|
||||
gdk_display_init (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
display->double_click_time = 250;
|
||||
display->double_click_distance = 5;
|
||||
|
||||
@@ -334,26 +304,22 @@ gdk_display_init (GdkDisplay *display)
|
||||
|
||||
g_queue_init (&display->queued_events);
|
||||
|
||||
priv->debug_flags = _gdk_debug_flags;
|
||||
display->debug_flags = _gdk_debug_flags;
|
||||
|
||||
priv->composited = TRUE;
|
||||
priv->rgba = TRUE;
|
||||
priv->input_shapes = TRUE;
|
||||
display->composited = TRUE;
|
||||
display->rgba = TRUE;
|
||||
display->input_shapes = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_dispose (GObject *object)
|
||||
{
|
||||
GdkDisplay *display = GDK_DISPLAY (object);
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
_gdk_display_manager_remove_display (gdk_display_manager_get (), display);
|
||||
|
||||
g_queue_clear (&display->queued_events);
|
||||
|
||||
g_clear_object (&priv->gl_context);
|
||||
g_clear_error (&priv->gl_error);
|
||||
|
||||
G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -418,11 +384,11 @@ gdk_display_is_closed (GdkDisplay *display)
|
||||
* gdk_display_get_event:
|
||||
* @display: a `GdkDisplay`
|
||||
*
|
||||
* Gets the next `GdkEvent` to be processed for @display,
|
||||
* fetching events from the windowing system if necessary.
|
||||
* Gets the next `GdkEvent` to be processed for @display, fetching events from the
|
||||
* windowing system if necessary.
|
||||
*
|
||||
* Returns: (nullable) (transfer full): the next `GdkEvent`
|
||||
* to be processed
|
||||
* Returns: (nullable) (transfer full): the next `GdkEvent` to be processed,
|
||||
* or %NULL if no events are pending
|
||||
*/
|
||||
GdkEvent *
|
||||
gdk_display_get_event (GdkDisplay *display)
|
||||
@@ -1032,25 +998,21 @@ gdk_display_get_primary_clipboard (GdkDisplay *display)
|
||||
gboolean
|
||||
gdk_display_supports_input_shapes (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
return priv->input_shapes;
|
||||
return display->input_shapes;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_input_shapes (GdkDisplay *display,
|
||||
gboolean input_shapes)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (priv->input_shapes == input_shapes)
|
||||
if (display->input_shapes == input_shapes)
|
||||
return;
|
||||
|
||||
priv->input_shapes = input_shapes;
|
||||
display->input_shapes = input_shapes;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_INPUT_SHAPES]);
|
||||
}
|
||||
@@ -1195,136 +1157,32 @@ gdk_display_get_keymap (GdkDisplay *display)
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_init_gl (GdkDisplay *self)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
GdkGLContext *context;
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
gint64 before2 G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (self, GL_DISABLE))
|
||||
{
|
||||
g_set_error_literal (&priv->gl_error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("GL support disabled via GDK_DEBUG"));
|
||||
return;
|
||||
}
|
||||
|
||||
context = GDK_DISPLAY_GET_CLASS (self)->init_gl (self, &priv->gl_error);
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
before2 = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (!gdk_gl_context_realize (context, &priv->gl_error))
|
||||
{
|
||||
g_object_unref (context);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_profiler_end_mark (before2, "realize OpenGL context", NULL);
|
||||
|
||||
/* Only assign after realize, so GdkGLContext::realize() can use
|
||||
* gdk_display_get_gl_context() == NULL to differentiate between
|
||||
* the display's context and any other context.
|
||||
*/
|
||||
priv->gl_context = context;
|
||||
|
||||
gdk_profiler_end_mark (before, "initialize OpenGL", NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_prepare_gl:
|
||||
* @self: a `GdkDisplay`
|
||||
* @error: return location for a `GError`
|
||||
*
|
||||
* Checks that OpenGL is available for @self and ensures that it is
|
||||
* properly initialized.
|
||||
* When this fails, an @error will be set describing the error and this
|
||||
* function returns %FALSE.
|
||||
*
|
||||
* Note that even if this function succeeds, creating a `GdkGLContext`
|
||||
* may still fail.
|
||||
*
|
||||
* This function is idempotent. Calling it multiple times will just
|
||||
* return the same value or error.
|
||||
*
|
||||
* You never need to call this function, GDK will call it automatically
|
||||
* as needed. But you can use it as a check when setting up code that
|
||||
* might make use of OpenGL.
|
||||
*
|
||||
* Returns: %TRUE if the display supports OpenGL
|
||||
*
|
||||
* Since: 4.4
|
||||
**/
|
||||
gboolean
|
||||
gdk_display_prepare_gl (GdkDisplay *self,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (priv->gl_context)
|
||||
return TRUE;
|
||||
|
||||
if (priv->gl_error != NULL)
|
||||
{
|
||||
if (error)
|
||||
*error = g_error_copy (priv->gl_error);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_display_init_gl (self);
|
||||
|
||||
/* try again */
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_display_get_gl_context:
|
||||
* @self: the `GdkDisplay`
|
||||
* gdk_display_make_gl_context_current:
|
||||
* @display: a `GdkDisplay`
|
||||
* @context: (optional): a `GdkGLContext`
|
||||
*
|
||||
* Gets the GL context returned from [vfunc@Gdk.Display.init_gl]
|
||||
* previously.
|
||||
*
|
||||
* If that function has not been called yet or did fail, %NULL is
|
||||
* returned.
|
||||
* Call [method@Gdk.Display.prepare_gl] to avoid this.
|
||||
*
|
||||
* Returns: The `GdkGLContext`
|
||||
* Makes the given @context the current GL context, or unsets
|
||||
* the current GL context if @context is %NULL.
|
||||
*/
|
||||
GdkGLContext *
|
||||
gdk_display_get_gl_context (GdkDisplay *self)
|
||||
gboolean
|
||||
gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
return priv->gl_context;
|
||||
return GDK_DISPLAY_GET_CLASS (display)->make_gl_context_current (display, context);
|
||||
}
|
||||
|
||||
GdkDebugFlags
|
||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
return display ? priv->debug_flags : _gdk_debug_flags;
|
||||
return display ? display->debug_flags : _gdk_debug_flags;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
GdkDebugFlags flags)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
priv->debug_flags = flags;
|
||||
display->debug_flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1349,25 +1207,21 @@ gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
gboolean
|
||||
gdk_display_is_composited (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
return priv->composited;
|
||||
return display->composited;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_composited (GdkDisplay *display,
|
||||
gboolean composited)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (priv->composited == composited)
|
||||
if (display->composited == composited)
|
||||
return;
|
||||
|
||||
priv->composited = composited;
|
||||
display->composited = composited;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_COMPOSITED]);
|
||||
}
|
||||
@@ -1394,25 +1248,21 @@ gdk_display_set_composited (GdkDisplay *display,
|
||||
gboolean
|
||||
gdk_display_is_rgba (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
return priv->rgba;
|
||||
return display->rgba;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_rgba (GdkDisplay *display,
|
||||
gboolean rgba)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (priv->rgba == rgba)
|
||||
if (display->rgba == rgba)
|
||||
return;
|
||||
|
||||
priv->rgba = rgba;
|
||||
display->rgba = rgba;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_RGBA]);
|
||||
}
|
||||
|
||||
@@ -68,10 +68,6 @@ gboolean gdk_display_is_rgba (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
gboolean gdk_display_prepare_gl (GdkDisplay *self,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay *gdk_display_get_default (void);
|
||||
|
||||
|
||||
@@ -323,8 +323,7 @@ gdk_display_manager_get_default_display (GdkDisplayManager *manager)
|
||||
* Gets the default `GdkDisplay`.
|
||||
*
|
||||
* This is a convenience function for:
|
||||
*
|
||||
* gdk_display_manager_get_default_display (gdk_display_manager_get ())
|
||||
* `gdk_display_manager_get_default_display (gdk_display_manager_get ())`.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a `GdkDisplay`, or %NULL if
|
||||
* there is no default display
|
||||
|
||||
@@ -102,6 +102,11 @@ struct _GdkDisplay
|
||||
|
||||
guint vulkan_refcount;
|
||||
#endif /* GDK_RENDERING_VULKAN */
|
||||
guint rgba : 1;
|
||||
guint composited : 1;
|
||||
guint input_shapes : 1;
|
||||
|
||||
GdkDebugFlags debug_flags;
|
||||
|
||||
GList *seats;
|
||||
};
|
||||
@@ -140,8 +145,8 @@ struct _GdkDisplayClass
|
||||
|
||||
GdkKeymap * (*get_keymap) (GdkDisplay *display);
|
||||
|
||||
GdkGLContext * (*init_gl) (GdkDisplay *display,
|
||||
GError **error);
|
||||
gboolean (*make_gl_context_current) (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
GdkSeat * (*get_default_seat) (GdkDisplay *display);
|
||||
|
||||
@@ -206,7 +211,8 @@ GdkSurface * gdk_display_create_surface (GdkDisplay *display
|
||||
int width,
|
||||
int height);
|
||||
|
||||
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
|
||||
gboolean gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
void gdk_display_set_rgba (GdkDisplay *display,
|
||||
gboolean rgba);
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate;
|
||||
|
||||
struct _GdkDrawContextPrivate {
|
||||
GdkDisplay *display;
|
||||
GdkSurface *surface;
|
||||
|
||||
cairo_region_t *frame_region;
|
||||
@@ -78,7 +77,6 @@ gdk_draw_context_dispose (GObject *gobject)
|
||||
priv->surface->draw_contexts = g_slist_remove (priv->surface->draw_contexts, context);
|
||||
g_clear_object (&priv->surface);
|
||||
}
|
||||
g_clear_object (&priv->display);
|
||||
|
||||
G_OBJECT_CLASS (gdk_draw_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
@@ -94,31 +92,10 @@ gdk_draw_context_set_property (GObject *gobject,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
if (priv->display != NULL)
|
||||
{
|
||||
g_assert (g_value_get_object (value) == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->display = g_value_dup_object (value);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
priv->surface = g_value_dup_object (value);
|
||||
if (priv->surface)
|
||||
{
|
||||
priv->surface->draw_contexts = g_slist_prepend (priv->surface->draw_contexts, context);
|
||||
if (priv->display)
|
||||
{
|
||||
g_assert (priv->display == gdk_surface_get_display (priv->surface));
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->display = g_object_ref (gdk_surface_get_display (priv->surface));
|
||||
}
|
||||
}
|
||||
g_assert (priv->surface != NULL);
|
||||
priv->surface->draw_contexts = g_slist_prepend (priv->surface->draw_contexts, context);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -171,8 +148,7 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
||||
P_("Display"),
|
||||
P_("The GDK display used to create the context"),
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
@@ -252,7 +228,7 @@ gdk_draw_context_get_display (GdkDrawContext *context)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
|
||||
|
||||
return priv->display;
|
||||
return priv->surface ? gdk_surface_get_display (priv->surface) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -294,11 +294,8 @@ gdk_drop_finalize (GObject *object)
|
||||
|
||||
/* someone forgot to send a LEAVE signal */
|
||||
g_warn_if_fail (!priv->entered);
|
||||
|
||||
/* Should we emit finish() here if necessary?
|
||||
* For now that's the backends' job
|
||||
*/
|
||||
g_warn_if_fail (priv->state != GDK_DROP_STATE_DROPPING);
|
||||
* For now that's the backends' job */
|
||||
|
||||
g_clear_object (&priv->device);
|
||||
g_clear_object (&priv->drag);
|
||||
@@ -574,7 +571,7 @@ gdk_drop_get_drag (GdkDrop *self)
|
||||
* the ones provided by [method@Gdk.Drop.get_actions]. Those actions may
|
||||
* change in the future, even depending on the actions you provide here.
|
||||
*
|
||||
* The @preferred action is a hint to the drag-and-drop mechanism about which
|
||||
* The @preferred action is a hint to the drag'n'drop mechanism about which
|
||||
* action to use when multiple actions are possible.
|
||||
*
|
||||
* This function should be called by drag destinations in response to
|
||||
@@ -865,7 +862,7 @@ gdk_drop_read_value_internal (GdkDrop *self,
|
||||
* then call [method@Gdk.Drop.read_value_finish] to get the resulting
|
||||
* `GValue`.
|
||||
*
|
||||
* For local drag-and-drop operations that are available in the given
|
||||
* For local drag'n'drop operations that are available in the given
|
||||
* `GType`, the value will be copied directly. Otherwise, GDK will
|
||||
* try to use [func@Gdk.content_deserialize_async] to convert the data.
|
||||
*/
|
||||
|
||||
@@ -481,11 +481,11 @@ _gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
|
||||
* for the current frame or a recent frame.
|
||||
*
|
||||
* The `GdkFrameTimings` object may not yet be complete: see
|
||||
* [method@Gdk.FrameTimings.get_complete] and
|
||||
* [method@Gdk.FrameClock.get_history_start].
|
||||
* [method@Gdk.FrameTimings.get_complete].
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the `GdkFrameTimings` object
|
||||
* for the specified frame, or %NULL if it is not available
|
||||
* for the specified frame, or %NULL if it is not available. See
|
||||
* [method@Gdk.FrameClock.get_history_start].
|
||||
*/
|
||||
GdkFrameTimings *
|
||||
gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
|
||||
|
||||
@@ -89,6 +89,8 @@
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
typedef struct {
|
||||
GdkGLContext *shared_context;
|
||||
|
||||
int major;
|
||||
int minor;
|
||||
int gl_version;
|
||||
@@ -125,28 +127,7 @@ G_DEFINE_QUARK (gdk-gl-error-quark, gdk_gl_error)
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, GDK_TYPE_DRAW_CONTEXT)
|
||||
|
||||
typedef struct _MaskedContext MaskedContext;
|
||||
|
||||
static inline MaskedContext *
|
||||
mask_context (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
return (MaskedContext *) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (context) | (surfaceless ? 1 : 0));
|
||||
}
|
||||
|
||||
static inline GdkGLContext *
|
||||
unmask_context (MaskedContext *mask)
|
||||
{
|
||||
return GDK_GL_CONTEXT (GSIZE_TO_POINTER (GPOINTER_TO_SIZE (mask) & ~(gsize) 1));
|
||||
}
|
||||
|
||||
static void
|
||||
unref_unmasked (gpointer data)
|
||||
{
|
||||
g_object_unref (unmask_context (data));
|
||||
}
|
||||
|
||||
static GPrivate thread_current_context = G_PRIVATE_INIT (unref_unmasked);
|
||||
static GPrivate thread_current_context = G_PRIVATE_INIT (g_object_unref);
|
||||
|
||||
static void
|
||||
gdk_gl_context_clear_old_updated_area (GdkGLContext *context)
|
||||
@@ -163,14 +144,17 @@ static void
|
||||
gdk_gl_context_dispose (GObject *gobject)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
MaskedContext *current;
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLContext *current;
|
||||
|
||||
gdk_gl_context_clear_old_updated_area (context);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (unmask_context (current) == context)
|
||||
if (current == context)
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
|
||||
g_clear_object (&priv->shared_context);
|
||||
|
||||
G_OBJECT_CLASS (gdk_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
@@ -190,10 +174,17 @@ gdk_gl_context_set_property (GObject *gobject,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SHARED_CONTEXT:
|
||||
g_assert (g_value_get_object (value) == NULL);
|
||||
{
|
||||
GdkGLContext *context = g_value_get_object (value);
|
||||
|
||||
if (context != NULL)
|
||||
priv->shared_context = g_object_ref (context);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -207,10 +198,12 @@ gdk_gl_context_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SHARED_CONTEXT:
|
||||
g_value_set_object (value, NULL);
|
||||
g_value_set_object (value, priv->shared_context);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -340,27 +333,23 @@ gdk_gl_context_real_get_damage (GdkGLContext *context)
|
||||
});
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_is_shared (GdkGLContext *self,
|
||||
GdkGLContext *other)
|
||||
{
|
||||
if (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self)) != gdk_draw_context_get_display (GDK_DRAW_CONTEXT (other)))
|
||||
return FALSE;
|
||||
|
||||
/* XXX: Should we check es or legacy here? */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface;
|
||||
GdkGLContext *shared;
|
||||
cairo_region_t *damage;
|
||||
int ww, wh;
|
||||
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
if (shared)
|
||||
{
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (GDK_DRAW_CONTEXT (shared))->begin_frame (GDK_DRAW_CONTEXT (shared), region);
|
||||
return;
|
||||
}
|
||||
|
||||
damage = GDK_GL_CONTEXT_GET_CLASS (context)->get_damage (context);
|
||||
|
||||
if (context->old_updated_area[1])
|
||||
@@ -390,6 +379,15 @@ static void
|
||||
gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkGLContext *shared;
|
||||
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
if (shared)
|
||||
{
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (GDK_DRAW_CONTEXT (shared))->end_frame (GDK_DRAW_CONTEXT (shared), painted);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -408,7 +406,6 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
|
||||
klass->realize = gdk_gl_context_real_realize;
|
||||
klass->get_damage = gdk_gl_context_real_get_damage;
|
||||
klass->is_shared = gdk_gl_context_real_is_shared;
|
||||
|
||||
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
|
||||
draw_context_class->end_frame = gdk_gl_context_real_end_frame;
|
||||
@@ -417,13 +414,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
/**
|
||||
* GdkGLContext:shared-context: (attributes org.gtk.Property.get=gdk_gl_context_get_shared_context)
|
||||
*
|
||||
* Always %NULL
|
||||
*
|
||||
* As many contexts can share data now and no single shared context exists
|
||||
* anymore, this function has been deprecated and now always returns %NULL.
|
||||
*
|
||||
* Deprecated: 4.4: Use [method@Gdk.GLContext.is_shared] to check if contexts
|
||||
* can be shared.
|
||||
* The `GdkGLContext` that this context is sharing data with, or %NULL
|
||||
*/
|
||||
obj_pspecs[PROP_SHARED_CONTEXT] =
|
||||
g_param_spec_object ("shared-context",
|
||||
@@ -432,8 +423,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
GDK_TYPE_GL_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_DEPRECATED);
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
gobject_class->set_property = gdk_gl_context_set_property;
|
||||
gobject_class->get_property = gdk_gl_context_get_property;
|
||||
@@ -451,21 +441,6 @@ gdk_gl_context_init (GdkGLContext *self)
|
||||
priv->use_es = -1;
|
||||
}
|
||||
|
||||
/* Must have called gdk_display_prepare_gl() before */
|
||||
GdkGLContext *
|
||||
gdk_gl_context_new_for_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkGLContext *shared = gdk_display_get_gl_context (display);
|
||||
|
||||
/* assert gdk_display_prepare_gl() had been called */
|
||||
g_assert (shared);
|
||||
|
||||
return g_object_new (G_OBJECT_TYPE (shared),
|
||||
"surface", surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GdkGLContextPaintData *
|
||||
gdk_gl_context_get_paint_data (GdkGLContext *context)
|
||||
{
|
||||
@@ -837,42 +812,6 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
priv->is_legacy = !!is_legacy;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_is_shared:
|
||||
* @self: a `GdkGLContext`
|
||||
* @other: the `GdkGLContext` that should be compatible with @self
|
||||
*
|
||||
* Checks if the two GL contexts can share resources.
|
||||
*
|
||||
* When they can, the texture IDs from @other can be used in @self. This
|
||||
* is particularly useful when passing `GdkGLTexture` objects between
|
||||
* different contexts.
|
||||
*
|
||||
* Contexts created for the same display with the same properties will
|
||||
* always be compatible, even if they are created for different surfaces.
|
||||
* For other contexts it depends on the GL backend.
|
||||
*
|
||||
* Both contexts must be realized for this check to succeed. If either one
|
||||
* is not, this function will return %FALSE.
|
||||
*
|
||||
* Returns: %TRUE if the two GL contexts are compatible.
|
||||
*/
|
||||
gboolean
|
||||
gdk_gl_context_is_shared (GdkGLContext *self,
|
||||
GdkGLContext *other)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
GdkGLContextPrivate *priv_other = gdk_gl_context_get_instance_private (other);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (other), FALSE);
|
||||
|
||||
if (!priv->realized || !priv_other->realized)
|
||||
return FALSE;
|
||||
|
||||
return GDK_GL_CONTEXT_GET_CLASS (self)->is_shared (self, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_set_use_es:
|
||||
* @context: a `GdkGLContext`
|
||||
@@ -1153,16 +1092,12 @@ void
|
||||
gdk_gl_context_make_current (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
MaskedContext *current, *masked_context;
|
||||
gboolean surfaceless;
|
||||
GdkGLContext *current;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
|
||||
masked_context = mask_context (context, surfaceless);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current == masked_context)
|
||||
if (current == context)
|
||||
return;
|
||||
|
||||
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
||||
@@ -1179,15 +1114,11 @@ gdk_gl_context_make_current (GdkGLContext *context)
|
||||
}
|
||||
}
|
||||
|
||||
if (!GDK_GL_CONTEXT_GET_CLASS (context)->make_current (context, surfaceless))
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), context))
|
||||
{
|
||||
g_warning ("gdk_gl_context_make_current() failed");
|
||||
return;
|
||||
g_private_replace (&thread_current_context, g_object_ref (context));
|
||||
gdk_gl_context_check_extensions (context);
|
||||
}
|
||||
|
||||
g_object_ref (context);
|
||||
g_private_replace (&thread_current_context, masked_context);
|
||||
gdk_gl_context_check_extensions (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1226,22 +1157,18 @@ gdk_gl_context_get_surface (GdkGLContext *context)
|
||||
* gdk_gl_context_get_shared_context: (attributes org.gtk.Method.get_property=shared-context)
|
||||
* @context: a `GdkGLContext`
|
||||
*
|
||||
* Used to retrieves the `GdkGLContext` that this @context share data with.
|
||||
* Retrieves the `GdkGLContext` that this @context share data with.
|
||||
*
|
||||
* As many contexts can share data now and no single shared context exists
|
||||
* anymore, this function has been deprecated and now always returns %NULL.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): %NULL
|
||||
*
|
||||
* Deprecated: 4.4: Use [method@Gdk.GLContext.is_shared] to check if contexts
|
||||
* can be shared.
|
||||
* Returns: (nullable) (transfer none): a `GdkGLContext`
|
||||
*/
|
||||
GdkGLContext *
|
||||
gdk_gl_context_get_shared_context (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
||||
|
||||
return NULL;
|
||||
return priv->shared_context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1281,14 +1208,12 @@ gdk_gl_context_get_version (GdkGLContext *context,
|
||||
void
|
||||
gdk_gl_context_clear_current (void)
|
||||
{
|
||||
MaskedContext *current;
|
||||
GdkGLContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current != NULL)
|
||||
{
|
||||
GdkGLContext *context = unmask_context (current);
|
||||
|
||||
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (current)), NULL))
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
}
|
||||
}
|
||||
@@ -1303,11 +1228,11 @@ gdk_gl_context_clear_current (void)
|
||||
GdkGLContext *
|
||||
gdk_gl_context_get_current (void)
|
||||
{
|
||||
MaskedContext *current;
|
||||
GdkGLContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
|
||||
return unmask_context (current);
|
||||
return current;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -45,8 +45,8 @@ GType gdk_gl_context_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_gl_context_get_display (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_gl_context_get_surface (GdkGLContext *context);
|
||||
GDK_DEPRECATED_IN_4_4_FOR(gdk_gl_context_is_shared)
|
||||
GdkSurface * gdk_gl_context_get_surface (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkGLContext * gdk_gl_context_get_shared_context (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_gl_context_get_version (GdkGLContext *context,
|
||||
@@ -54,9 +54,6 @@ void gdk_gl_context_get_version (GdkGLContext *
|
||||
int *minor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_gl_context_is_legacy (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
gboolean gdk_gl_context_is_shared (GdkGLContext *self,
|
||||
GdkGLContext *other);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_gl_context_set_required_version (GdkGLContext *context,
|
||||
|
||||
@@ -27,13 +27,6 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Version requirements for EGL contexts.
|
||||
*
|
||||
* If you add support for EGL to your backend, please require this.
|
||||
*/
|
||||
#define GDK_EGL_MIN_VERSION_MAJOR (1)
|
||||
#define GDK_EGL_MIN_VERSION_MINOR (4)
|
||||
|
||||
#define GDK_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
||||
#define GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT))
|
||||
#define GDK_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
||||
@@ -52,16 +45,10 @@ struct _GdkGLContextClass
|
||||
{
|
||||
GdkDrawContextClass parent_class;
|
||||
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
|
||||
gboolean (* make_current) (GdkGLContext *context,
|
||||
gboolean surfaceless);
|
||||
gboolean (* clear_current) (GdkGLContext *context);
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
|
||||
gboolean (* is_shared) (GdkGLContext *self,
|
||||
GdkGLContext *other);
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -86,8 +73,6 @@ typedef struct {
|
||||
guint use_es : 1;
|
||||
} GdkGLContextPaintData;
|
||||
|
||||
GdkGLContext * gdk_gl_context_new_for_surface (GdkSurface *surface);
|
||||
|
||||
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
gboolean is_legacy);
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ G_BEGIN_DECLS
|
||||
* CAIRO_FORMAT_ARGB32 is represented by different `GdkMemoryFormats`
|
||||
* on architectures with different endiannesses.
|
||||
*
|
||||
* Its naming is modelled after
|
||||
* [VkFormat](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkFormat)
|
||||
* Its naming is modelled after VkFormat (see
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkFormat
|
||||
* for details).
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
@@ -1066,22 +1066,86 @@ gdk_surface_get_mapped (GdkSurface *surface)
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
GError **error)
|
||||
gdk_surface_get_shared_data_gl_context (GdkSurface *surface)
|
||||
{
|
||||
if (!gdk_display_prepare_gl (surface->display, error))
|
||||
static int in_shared_data_creation;
|
||||
GdkDisplay *display;
|
||||
GdkGLContext *context;
|
||||
|
||||
if (in_shared_data_creation)
|
||||
return NULL;
|
||||
|
||||
in_shared_data_creation = 1;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
context = (GdkGLContext *)g_object_get_data (G_OBJECT (display), "gdk-gl-shared-data-context");
|
||||
if (context == NULL)
|
||||
{
|
||||
GError *error = NULL;
|
||||
context = GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface, FALSE, NULL, &error);
|
||||
if (context == NULL)
|
||||
{
|
||||
g_warning ("Failed to create shared context: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
gdk_gl_context_realize (context, &error);
|
||||
if (context == NULL)
|
||||
{
|
||||
g_warning ("Failed to realize shared context: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
|
||||
g_object_set_data (G_OBJECT (display), "gdk-gl-shared-data-context", context);
|
||||
}
|
||||
|
||||
in_shared_data_creation = 0;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
GError **error)
|
||||
{
|
||||
GError *internal_error = NULL;
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (surface->display, GL_DISABLE))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("GL support disabled via GDK_DEBUG"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (surface->gl_paint_context == NULL)
|
||||
{
|
||||
surface->gl_paint_context = gdk_surface_create_gl_context (surface, error);
|
||||
if (surface->gl_paint_context == NULL)
|
||||
return NULL;
|
||||
GdkSurfaceClass *class = GDK_SURFACE_GET_CLASS (surface);
|
||||
|
||||
if (class->create_gl_context == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("The current backend does not support OpenGL"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->gl_paint_context =
|
||||
class->create_gl_context (surface, TRUE, NULL, &internal_error);
|
||||
}
|
||||
|
||||
if (!gdk_gl_context_realize (surface->gl_paint_context, error))
|
||||
if (internal_error != NULL)
|
||||
{
|
||||
g_clear_object (&surface->gl_paint_context);
|
||||
g_propagate_error (error, internal_error);
|
||||
g_clear_object (&(surface->gl_paint_context));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gdk_gl_context_realize (surface->gl_paint_context, &internal_error);
|
||||
if (internal_error != NULL)
|
||||
{
|
||||
g_propagate_error (error, internal_error);
|
||||
g_clear_object (&(surface->gl_paint_context));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1106,13 +1170,19 @@ GdkGLContext *
|
||||
gdk_surface_create_gl_context (GdkSurface *surface,
|
||||
GError **error)
|
||||
{
|
||||
GdkGLContext *paint_context;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
if (!gdk_display_prepare_gl (surface->display, error))
|
||||
paint_context = gdk_surface_get_paint_gl_context (surface, error);
|
||||
if (paint_context == NULL)
|
||||
return NULL;
|
||||
|
||||
return gdk_gl_context_new_for_surface (surface);
|
||||
return GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface,
|
||||
FALSE,
|
||||
paint_context,
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -160,6 +160,10 @@ struct _GdkSurfaceClass
|
||||
|
||||
void (* set_opaque_region) (GdkSurface *surface,
|
||||
cairo_region_t *region);
|
||||
GdkGLContext *(*create_gl_context) (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
void (* request_layout) (GdkSurface *surface);
|
||||
gboolean (* compute_size) (GdkSurface *surface);
|
||||
};
|
||||
@@ -262,6 +266,7 @@ void _gdk_surface_update_size (GdkSurface *surface);
|
||||
|
||||
GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
GError **error);
|
||||
GdkGLContext * gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
|
||||
|
||||
gboolean gdk_surface_handle_event (GdkEvent *event);
|
||||
GdkSeat * gdk_surface_get_seat_from_event (GdkSurface *surface,
|
||||
|
||||
@@ -533,7 +533,7 @@ gdk_texture_get_render_data (GdkTexture *self,
|
||||
/**
|
||||
* gdk_texture_save_to_png:
|
||||
* @texture: a `GdkTexture`
|
||||
* @filename: (type filename): the filename to store to
|
||||
* @filename: the filename to store to
|
||||
*
|
||||
* Store the given @texture to the @filename as a PNG file.
|
||||
*
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
#import "GdkMacosGLView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdrop-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacospopupsurface-private.h"
|
||||
@@ -289,9 +287,6 @@ typedef NSString *CALayerContentsGravity;
|
||||
[self setContentView:view];
|
||||
[view release];
|
||||
|
||||
/* TODO: We might want to make this more extensible at some point */
|
||||
_gdk_macos_clipboard_register_drag_types (self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -602,86 +597,25 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint location = [sender draggingLocation];
|
||||
NSDragOperation ret;
|
||||
GdkMacosDrop *drop;
|
||||
|
||||
if (!(drop = _gdk_macos_drop_new ([self gdkSurface], sender)))
|
||||
return NSDragOperationNone;
|
||||
|
||||
_gdk_macos_display_set_drop ([self gdkDisplay],
|
||||
[sender draggingSequenceNumber],
|
||||
GDK_DROP (drop));
|
||||
|
||||
gdk_drop_emit_enter_event (GDK_DROP (drop),
|
||||
TRUE,
|
||||
location.x,
|
||||
GDK_SURFACE (gdk_surface)->height - location.y,
|
||||
GDK_CURRENT_TIME);
|
||||
|
||||
ret = _gdk_macos_drop_operation (drop);
|
||||
|
||||
g_object_unref (drop);
|
||||
|
||||
return ret;
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
-(void)draggingEnded:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
_gdk_macos_display_set_drop ([self gdkDisplay], [sender draggingSequenceNumber], NULL);
|
||||
}
|
||||
|
||||
-(void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSInteger sequence_number = [sender draggingSequenceNumber];
|
||||
GdkDrop *drop = _gdk_macos_display_find_drop ([self gdkDisplay], sequence_number);
|
||||
|
||||
if (drop != NULL)
|
||||
gdk_drop_emit_leave_event (drop, TRUE, GDK_CURRENT_TIME);
|
||||
|
||||
_gdk_macos_display_set_drop ([self gdkDisplay], sequence_number, NULL);
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSInteger sequence_number = [sender draggingSequenceNumber];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
GdkDrop *drop = _gdk_macos_display_find_drop (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
NSPoint location = [sender draggingLocation];
|
||||
|
||||
if (drop == NULL)
|
||||
return NSDragOperationNone;
|
||||
|
||||
_gdk_macos_drop_update_actions (GDK_MACOS_DROP (drop), sender);
|
||||
|
||||
gdk_drop_emit_motion_event (drop,
|
||||
TRUE,
|
||||
location.x,
|
||||
GDK_SURFACE (gdk_surface)->height - location.y,
|
||||
GDK_CURRENT_TIME);
|
||||
|
||||
return _gdk_macos_drop_operation (GDK_MACOS_DROP (drop));
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSInteger sequence_number = [sender draggingSequenceNumber];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
GdkDrop *drop = _gdk_macos_display_find_drop (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
NSPoint location = [sender draggingLocation];
|
||||
|
||||
if (drop == NULL)
|
||||
return NO;
|
||||
|
||||
gdk_drop_emit_drop_event (drop,
|
||||
TRUE,
|
||||
location.x,
|
||||
GDK_SURFACE (gdk_surface)->height - location.y,
|
||||
GDK_CURRENT_TIME);
|
||||
|
||||
gdk_drop_emit_leave_event (drop, TRUE, GDK_CURRENT_TIME);
|
||||
|
||||
return GDK_MACOS_DROP (drop)->finish_action != 0;
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)wantsPeriodicDraggingUpdates
|
||||
|
||||
@@ -35,24 +35,11 @@ typedef NSString *NSPasteboardType;
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
||||
|
||||
GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
|
||||
void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
|
||||
NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||
void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
|
||||
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
|
||||
void _gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error);
|
||||
GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
|
||||
void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
|
||||
NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||
|
||||
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||
{
|
||||
|
||||
@@ -172,15 +172,17 @@ populate_content_formats (GdkContentFormatsBuilder *builder,
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
load_offer_formats (NSPasteboard *pasteboard)
|
||||
load_offer_formats (GdkMacosClipboard *self)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
for (NSPasteboardType type in [pasteboard types])
|
||||
for (NSPasteboardType type in [self->pasteboard types])
|
||||
populate_content_formats (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
@@ -199,7 +201,7 @@ _gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||
|
||||
change_count = [self->pasteboard changeCount];
|
||||
|
||||
formats = load_offer_formats (self->pasteboard);
|
||||
formats = load_offer_formats (self);
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
@@ -223,13 +225,125 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
_gdk_macos_pasteboard_read_async (G_OBJECT (clipboard),
|
||||
GDK_MACOS_CLIPBOARD (clipboard)->pasteboard,
|
||||
formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)clipboard;
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_clipboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (GDK_MACOS_CLIPBOARD (clipboard));
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [self->pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[self->pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:self->pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
@@ -238,7 +352,15 @@ _gdk_macos_clipboard_read_finish (GdkClipboard *clipboard,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
return _gdk_macos_pasteboard_read_finish (G_OBJECT (clipboard), result, out_mime_type, error);
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (clipboard));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -500,170 +622,4 @@ on_data_ready_cb (GObject *object,
|
||||
write_request_free (wr);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_clipboard_register_drag_types (NSWindow *window)
|
||||
{
|
||||
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
|
||||
PTYPE(PBOARD),
|
||||
PTYPE(URL),
|
||||
PTYPE(FILE_URL),
|
||||
PTYPE(COLOR),
|
||||
PTYPE(TIFF),
|
||||
PTYPE(PNG),
|
||||
nil]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
GdkContentFormats *
|
||||
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
return load_offer_formats (pasteboard);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (pasteboard != NULL);
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (object, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (pasteboard);
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
@@ -81,10 +81,6 @@ struct _GdkMacosDisplay
|
||||
/* The surface that is receiving keyboard events */
|
||||
GdkMacosSurface *keyboard_surface;
|
||||
|
||||
/* [NSDraggingInfo draggingSequenceNumber] to GdkMacosDr(ag,op) */
|
||||
GHashTable *active_drags;
|
||||
GHashTable *active_drops;
|
||||
|
||||
/* Used to translate from quartz coordinate space to GDK */
|
||||
int width;
|
||||
int height;
|
||||
@@ -164,16 +160,6 @@ void _gdk_macos_display_warp_pointer (GdkMacosDisp
|
||||
int x,
|
||||
int y);
|
||||
NSEvent *_gdk_macos_display_get_nsevent (GdkEvent *event);
|
||||
GdkDrag *_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number);
|
||||
GdkDrop *_gdk_macos_display_find_drop (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number);
|
||||
void _gdk_macos_display_set_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number,
|
||||
GdkDrag *drag);
|
||||
void _gdk_macos_display_set_drop (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number,
|
||||
GdkDrop *drop);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -788,9 +788,6 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
NSRect view_frame;
|
||||
|
||||
view = (GdkMacosBaseView *)[nswindow contentView];
|
||||
if (!GDK_IS_MACOS_BASE_VIEW (view))
|
||||
goto find_under_pointer;
|
||||
|
||||
surface = GDK_SURFACE ([view gdkSurface]);
|
||||
|
||||
point = [nsevent locationInWindow];
|
||||
@@ -849,8 +846,6 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
}
|
||||
}
|
||||
|
||||
find_under_pointer:
|
||||
|
||||
if (!surface)
|
||||
{
|
||||
/* Fallback used when no NSSurface set. This happens e.g. when
|
||||
@@ -869,24 +864,17 @@ find_under_pointer:
|
||||
static GdkMacosSurface *
|
||||
find_surface_for_keyboard_event (NSEvent *nsevent)
|
||||
{
|
||||
NSView *nsview = [[nsevent window] contentView];
|
||||
GdkMacosBaseView *view = (GdkMacosBaseView *)[[nsevent window] contentView];
|
||||
GdkSurface *surface = GDK_SURFACE ([view gdkSurface]);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkSeat *seat = gdk_display_get_default_seat (display);
|
||||
GdkDevice *device = gdk_seat_get_keyboard (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (display, device);
|
||||
|
||||
if (GDK_IS_MACOS_BASE_VIEW (nsview))
|
||||
{
|
||||
GdkMacosBaseView *view = (GdkMacosBaseView *)nsview;
|
||||
GdkSurface *surface = GDK_SURFACE ([view gdkSurface]);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkSeat *seat = gdk_display_get_default_seat (display);
|
||||
GdkDevice *device = gdk_seat_get_keyboard (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (display, device);
|
||||
if (grab && grab->surface && !grab->owner_events)
|
||||
return GDK_MACOS_SURFACE (grab->surface);
|
||||
|
||||
if (grab && grab->surface && !grab->owner_events)
|
||||
return GDK_MACOS_SURFACE (grab->surface);
|
||||
|
||||
return GDK_MACOS_SURFACE (surface);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return GDK_MACOS_SURFACE (surface);
|
||||
}
|
||||
|
||||
static GdkMacosSurface *
|
||||
@@ -1102,8 +1090,7 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
||||
return NULL;
|
||||
|
||||
if (!(window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)) ||
|
||||
!GDK_IS_MACOS_WINDOW (window))
|
||||
if (!(window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)))
|
||||
return NULL;
|
||||
|
||||
/* Ignore events and break grabs while the window is being
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
#include "gdkmacoscairocontext-private.h"
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdrag-private.h"
|
||||
#include "gdkmacosdrop-private.h"
|
||||
#include "gdkmacosglcontext-private.h"
|
||||
#include "gdkmacoskeymap-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
@@ -637,13 +635,17 @@ gdk_macos_display_load_clipboard (GdkMacosDisplay *self)
|
||||
GDK_DISPLAY (self)->clipboard = _gdk_macos_clipboard_new (self);
|
||||
}
|
||||
|
||||
static GdkGLContext *
|
||||
gdk_macos_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
static gboolean
|
||||
gdk_macos_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *gl_context)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||
"display", display,
|
||||
NULL);
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
||||
g_assert (!gl_context || GDK_IS_MACOS_GL_CONTEXT (gl_context));
|
||||
|
||||
if (gl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
return _gdk_macos_gl_context_make_current (GDK_MACOS_GL_CONTEXT (gl_context));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -661,8 +663,6 @@ gdk_macos_display_finalize (GObject *object)
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL);
|
||||
|
||||
g_clear_pointer (&self->active_drags, g_hash_table_unref);
|
||||
g_clear_pointer (&self->active_drops, g_hash_table_unref);
|
||||
g_clear_object (&GDK_DISPLAY (self)->clipboard);
|
||||
g_clear_pointer (&self->frame_source, g_source_unref);
|
||||
g_clear_object (&self->monitors);
|
||||
@@ -691,7 +691,7 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
|
||||
display_class->get_name = gdk_macos_display_get_name;
|
||||
display_class->get_setting = gdk_macos_display_get_setting;
|
||||
display_class->has_pending = gdk_macos_display_has_pending;
|
||||
display_class->init_gl = gdk_macos_display_init_gl;
|
||||
display_class->make_gl_context_current = gdk_macos_display_make_gl_context_current;
|
||||
display_class->notify_startup_complete = gdk_macos_display_notify_startup_complete;
|
||||
display_class->queue_events = gdk_macos_display_queue_events;
|
||||
display_class->sync = gdk_macos_display_sync;
|
||||
@@ -701,8 +701,6 @@ static void
|
||||
gdk_macos_display_init (GdkMacosDisplay *self)
|
||||
{
|
||||
self->monitors = g_list_store_new (GDK_TYPE_MONITOR);
|
||||
self->active_drags = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
|
||||
self->active_drops = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
|
||||
|
||||
gdk_display_set_composited (GDK_DISPLAY (self), TRUE);
|
||||
gdk_display_set_input_shapes (GDK_DISPLAY (self), FALSE);
|
||||
@@ -1115,55 +1113,3 @@ _gdk_macos_display_get_nsevent (GdkEvent *event)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkDrag *
|
||||
_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), NULL);
|
||||
|
||||
return g_hash_table_lookup (self->active_drags, GSIZE_TO_POINTER (sequence_number));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_set_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number,
|
||||
GdkDrag *drag)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (!drag || GDK_IS_MACOS_DRAG (drag));
|
||||
|
||||
if (drag)
|
||||
g_hash_table_insert (self->active_drags,
|
||||
GSIZE_TO_POINTER (sequence_number),
|
||||
g_object_ref (drag));
|
||||
else
|
||||
g_hash_table_remove (self->active_drags,
|
||||
GSIZE_TO_POINTER (sequence_number));
|
||||
}
|
||||
|
||||
GdkDrop *
|
||||
_gdk_macos_display_find_drop (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), NULL);
|
||||
|
||||
return g_hash_table_lookup (self->active_drops, GSIZE_TO_POINTER (sequence_number));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_set_drop (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number,
|
||||
GdkDrop *drop)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (!drop || GDK_IS_MACOS_DROP (drop));
|
||||
|
||||
if (drop)
|
||||
g_hash_table_insert (self->active_drops,
|
||||
GSIZE_TO_POINTER (sequence_number),
|
||||
g_object_ref (drop));
|
||||
else
|
||||
g_hash_table_remove (self->active_drops,
|
||||
GSIZE_TO_POINTER (sequence_number));
|
||||
}
|
||||
|
||||
@@ -326,10 +326,12 @@ gdk_drag_update (GdkDrag *drag,
|
||||
&suggested_action,
|
||||
&possible_actions);
|
||||
|
||||
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y);
|
||||
_gdk_macos_drag_surface_drag_motion (self->drag_surface,
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y,
|
||||
suggested_action,
|
||||
possible_actions,
|
||||
evtime);
|
||||
|
||||
if (!self->did_update)
|
||||
{
|
||||
@@ -337,8 +339,6 @@ gdk_drag_update (GdkDrag *drag,
|
||||
self->start_y = self->last_y;
|
||||
self->did_update = TRUE;
|
||||
}
|
||||
|
||||
gdk_drag_set_actions (drag, possible_actions);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -31,13 +31,19 @@ typedef struct _GdkMacosDragSurfaceClass GdkMacosDragSurfaceClass;
|
||||
#define GDK_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DRAG_SURFACE, GdkMacosDragSurface))
|
||||
#define GDK_IS_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG_SURFACE))
|
||||
|
||||
GType _gdk_macos_drag_surface_get_type (void);
|
||||
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
GType _gdk_macos_drag_surface_get_type (void);
|
||||
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_macos_drag_surface_drag_motion (GdkMacosDragSurface *self,
|
||||
int x_root,
|
||||
int y_root,
|
||||
GdkDragAction suggested_action,
|
||||
GdkDragAction possible_actions,
|
||||
guint32 evtime);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -123,3 +123,16 @@ _gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_surface_drag_motion (GdkMacosDragSurface *self,
|
||||
int x_root,
|
||||
int y_root,
|
||||
GdkDragAction suggested_action,
|
||||
GdkDragAction possible_actions,
|
||||
guint32 evtime)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DRAG_SURFACE (self));
|
||||
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self), x_root, y_root);
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DROP_PRIVATE_H__
|
||||
#define __GDK_MACOS_DROP_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkdropprivate.h"
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_DROP (gdk_macos_drop_get_type ())
|
||||
#define GDK_MACOS_DROP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DROP, GdkMacosDrop))
|
||||
#define GDK_MACOS_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_MACOS_DROP, GdkMacosDropClass))
|
||||
#define GDK_IS_MACOS_DROP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DROP))
|
||||
#define GDK_IS_MACOS_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_MACOS_DROP))
|
||||
#define GDK_MACOS_DROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_MACOS_DROP, GdkMacosDropClass))
|
||||
|
||||
typedef struct _GdkMacosDrop GdkMacosDrop;
|
||||
typedef struct _GdkMacosDropClass GdkMacosDropClass;
|
||||
|
||||
struct _GdkMacosDrop
|
||||
{
|
||||
GdkDrop parent_instance;
|
||||
|
||||
NSPasteboard *pasteboard;
|
||||
|
||||
GdkDragAction all_actions;
|
||||
GdkDragAction preferred_action;
|
||||
GdkDragAction finish_action;
|
||||
};
|
||||
|
||||
struct _GdkMacosDropClass
|
||||
{
|
||||
GdkDropClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_macos_drop_get_type (void) G_GNUC_CONST;
|
||||
GdkMacosDrop *_gdk_macos_drop_new (GdkMacosSurface *surface,
|
||||
id<NSDraggingInfo> info);
|
||||
NSDragOperation _gdk_macos_drop_operation (GdkMacosDrop *self);
|
||||
void _gdk_macos_drop_update_actions (GdkMacosDrop *self,
|
||||
id<NSDraggingInfo> info);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DROP_PRIVATE_H__ */
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdrag-private.h"
|
||||
#include "gdkmacosdrop-private.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosDrop, gdk_macos_drop, GDK_TYPE_DROP)
|
||||
|
||||
static void
|
||||
gdk_macos_drop_status (GdkDrop *drop,
|
||||
GdkDragAction actions,
|
||||
GdkDragAction preferred)
|
||||
{
|
||||
GdkMacosDrop *self = (GdkMacosDrop *)drop;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DROP (self));
|
||||
|
||||
self->all_actions = actions;
|
||||
self->preferred_action = preferred;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drop_read_async (GdkDrop *drop,
|
||||
GdkContentFormats *content_formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
_gdk_macos_pasteboard_read_async (G_OBJECT (drop),
|
||||
GDK_MACOS_DROP (drop)->pasteboard,
|
||||
content_formats,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
gdk_macos_drop_read_finish (GdkDrop *drop,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
return _gdk_macos_pasteboard_read_finish (G_OBJECT (drop), result, out_mime_type, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drop_finish (GdkDrop *drop,
|
||||
GdkDragAction action)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_DROP (drop));
|
||||
|
||||
GDK_MACOS_DROP (drop)->finish_action = action;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drop_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosDrop *self = (GdkMacosDrop *)object;
|
||||
|
||||
if (self->pasteboard)
|
||||
{
|
||||
[self->pasteboard release];
|
||||
self->pasteboard = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_drop_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drop_class_init (GdkMacosDropClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDropClass *drop_class = GDK_DROP_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_macos_drop_finalize;
|
||||
|
||||
drop_class->status = gdk_macos_drop_status;
|
||||
drop_class->read_async = gdk_macos_drop_read_async;
|
||||
drop_class->read_finish = gdk_macos_drop_read_finish;
|
||||
drop_class->finish = gdk_macos_drop_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drop_init (GdkMacosDrop *self)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drop_update_actions (GdkMacosDrop *self,
|
||||
id<NSDraggingInfo> info)
|
||||
{
|
||||
NSDragOperation op;
|
||||
GdkDragAction actions = 0;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DROP (self));
|
||||
|
||||
op = [info draggingSourceOperationMask];
|
||||
|
||||
if (op & NSDragOperationCopy)
|
||||
actions |= GDK_ACTION_COPY;
|
||||
|
||||
if (op & NSDragOperationLink)
|
||||
actions |= GDK_ACTION_LINK;
|
||||
|
||||
if (op & NSDragOperationMove)
|
||||
actions |= GDK_ACTION_MOVE;
|
||||
|
||||
gdk_drop_set_actions (GDK_DROP (self), actions);
|
||||
}
|
||||
|
||||
GdkMacosDrop *
|
||||
_gdk_macos_drop_new (GdkMacosSurface *surface,
|
||||
id<NSDraggingInfo> info)
|
||||
{
|
||||
GdkDrag *drag = NULL;
|
||||
GdkContentFormats *content_formats;
|
||||
GdkMacosDrop *self;
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
GdkSeat *seat;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (surface), NULL);
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
|
||||
display = gdk_surface_get_display (GDK_SURFACE (surface));
|
||||
seat = gdk_display_get_default_seat (display);
|
||||
device = gdk_seat_get_pointer (seat);
|
||||
drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), [info draggingSequenceNumber]);
|
||||
|
||||
content_formats = _gdk_macos_pasteboard_load_formats ([info draggingPasteboard]);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_DROP,
|
||||
"device", device,
|
||||
"drag", drag,
|
||||
"formats", content_formats,
|
||||
"surface", surface,
|
||||
NULL);
|
||||
|
||||
self->pasteboard = [[info draggingPasteboard] retain];
|
||||
|
||||
_gdk_macos_drop_update_actions (self, info);
|
||||
|
||||
gdk_content_formats_unref (content_formats);
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
NSDragOperation
|
||||
_gdk_macos_drop_operation (GdkMacosDrop *self)
|
||||
{
|
||||
if (self->preferred_action & GDK_ACTION_LINK)
|
||||
return NSDragOperationLink;
|
||||
|
||||
if (self->preferred_action & GDK_ACTION_MOVE)
|
||||
return NSDragOperationMove;
|
||||
|
||||
if (self->preferred_action & GDK_ACTION_COPY)
|
||||
return NSDragOperationCopy;
|
||||
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
@@ -19,14 +19,12 @@
|
||||
#ifndef __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||
#define __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||
|
||||
#include "gdkmacosglcontext.h"
|
||||
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosglcontext.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
@@ -57,6 +55,11 @@ struct _GdkMacosGLContextClass
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
|
||||
GdkGLContext *_gdk_macos_gl_context_new (GdkMacosSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gboolean _gdk_macos_gl_context_make_current (GdkMacosGLContext *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -145,7 +145,6 @@ ensure_gl_view (GdkMacosGLContext *self)
|
||||
[nsview setPostsFrameChangedNotifications: YES];
|
||||
[nsview setNeedsDisplay:YES];
|
||||
[nswindow setContentView:nsview];
|
||||
[nswindow makeFirstResponder:nsview];
|
||||
[nsview release];
|
||||
|
||||
if (self->dummy_view != NULL)
|
||||
@@ -170,12 +169,12 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
{
|
||||
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
|
||||
GdkSurface *surface;
|
||||
GdkDisplay *display;
|
||||
NSOpenGLContext *shared_gl_context = nil;
|
||||
NSOpenGLContext *gl_context;
|
||||
NSOpenGLPixelFormat *pixelFormat;
|
||||
CGLContextObj cgl_context;
|
||||
GdkGLContext *shared;
|
||||
GdkGLContext *shared_data;
|
||||
NSOpenGLContext *existing;
|
||||
GLint sync_to_framerate = 1;
|
||||
GLint validate = 0;
|
||||
@@ -192,16 +191,21 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
|
||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
display = gdk_gl_context_get_display (context);
|
||||
shared = gdk_display_get_gl_context (display);
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
shared_data = gdk_surface_get_shared_data_gl_context (surface);
|
||||
|
||||
if (shared != NULL)
|
||||
{
|
||||
if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
|
||||
return FALSE;
|
||||
}
|
||||
else if (shared_data != NULL)
|
||||
{
|
||||
if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared_data), error)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (display,
|
||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
|
||||
OPENGL,
|
||||
g_message ("Creating NSOpenGLContext (version %d.%d)",
|
||||
major, minor));
|
||||
@@ -248,7 +252,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
|
||||
GLint renderer_id = 0;
|
||||
[gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
|
||||
GDK_DISPLAY_NOTE (display,
|
||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
|
||||
OPENGL,
|
||||
g_message ("Created NSOpenGLContext[%p] using %s",
|
||||
gl_context,
|
||||
@@ -310,7 +314,9 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
* want to replace our damage region for the next frame (to avoid
|
||||
* doing it multiple times).
|
||||
*/
|
||||
ensure_gl_view (self);
|
||||
if (!self->is_attached &&
|
||||
gdk_gl_context_get_shared_context (GDK_GL_CONTEXT (context)))
|
||||
ensure_gl_view (self);
|
||||
|
||||
if (self->needs_resize)
|
||||
{
|
||||
@@ -403,57 +409,6 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context == current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context != current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[self->gl_context makeCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_macos_gl_context_get_damage (GdkGLContext *context)
|
||||
{
|
||||
@@ -522,4 +477,52 @@ gdk_macos_gl_context_init (GdkMacosGLContext *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
_gdk_macos_gl_context_new (GdkMacosSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkMacosGLContext *context;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (surface), NULL);
|
||||
g_return_val_if_fail (!share || GDK_IS_MACOS_GL_CONTEXT (share), NULL);
|
||||
|
||||
context = g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||
"surface", surface,
|
||||
"shared-context", share,
|
||||
NULL);
|
||||
|
||||
context->is_attached = !!attached;
|
||||
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_gl_context_make_current (GdkMacosGLContext *self)
|
||||
{
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
if (self->gl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context != current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[self->gl_context makeCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
@@ -348,7 +348,7 @@ _gdk_macos_seat_new (GdkMacosDisplay *display)
|
||||
|
||||
init_devices (self);
|
||||
|
||||
return GDK_SEAT (g_steal_pointer (&self));
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
static GdkDeviceToolType
|
||||
|
||||
@@ -332,7 +332,7 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
drag_surface = _gdk_macos_surface_new (GDK_MACOS_DISPLAY (surface->display),
|
||||
GDK_SURFACE_TEMP,
|
||||
surface,
|
||||
sx, sy, 1, 1);
|
||||
-99, -99, 1, 1);
|
||||
drag = g_object_new (GDK_TYPE_MACOS_DRAG,
|
||||
"drag-surface", drag_surface,
|
||||
"surface", surface,
|
||||
@@ -358,6 +358,20 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
return GDK_DRAG (g_steal_pointer (&drag));
|
||||
}
|
||||
|
||||
static GdkGLContext *
|
||||
gdk_macos_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkMacosSurface *self = (GdkMacosSurface *)surface;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
g_assert (!share || GDK_IS_GL_CONTEXT (share));
|
||||
|
||||
return _gdk_macos_gl_context_new (self, attached, share, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy)
|
||||
@@ -481,6 +495,7 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
|
||||
object_class->get_property = gdk_macos_surface_get_property;
|
||||
object_class->set_property = gdk_macos_surface_set_property;
|
||||
|
||||
surface_class->create_gl_context = gdk_macos_surface_create_gl_context;
|
||||
surface_class->destroy = gdk_macos_surface_destroy;
|
||||
surface_class->drag_begin = gdk_macos_surface_drag_begin;
|
||||
surface_class->get_device_state = gdk_macos_surface_get_device_state;
|
||||
|
||||
@@ -10,7 +10,6 @@ gdk_macos_sources = files([
|
||||
'gdkmacosdisplay-settings.c',
|
||||
'gdkmacosdisplay-translate.c',
|
||||
'gdkmacosdrag.c',
|
||||
'gdkmacosdrop.c',
|
||||
'gdkmacosdragsurface.c',
|
||||
'gdkmacosglcontext.c',
|
||||
'gdkmacoseventsource.c',
|
||||
|
||||
@@ -1550,7 +1550,6 @@ pointer_handle_leave (void *data,
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkEvent *event;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkDeviceGrabInfo *grab;
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
@@ -1562,11 +1561,8 @@ pointer_handle_leave (void *data,
|
||||
return;
|
||||
|
||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||
grab = _gdk_display_get_last_device_grab (seat->display,
|
||||
seat->logical_pointer);
|
||||
|
||||
if (seat->pointer_info.button_modifiers != 0 &&
|
||||
grab && grab->implicit)
|
||||
if (seat->pointer_info.button_modifiers != 0)
|
||||
{
|
||||
gulong display_serial;
|
||||
|
||||
@@ -3093,11 +3089,6 @@ seat_handle_capabilities (void *data,
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer)
|
||||
{
|
||||
g_clear_pointer (&seat->wp_pointer_gesture_swipe,
|
||||
zwp_pointer_gesture_swipe_v1_destroy);
|
||||
g_clear_pointer (&seat->wp_pointer_gesture_pinch,
|
||||
zwp_pointer_gesture_pinch_v1_destroy);
|
||||
|
||||
wl_pointer_release (seat->wl_pointer);
|
||||
seat->wl_pointer = NULL;
|
||||
gdk_seat_device_removed (GDK_SEAT (seat), seat->pointer);
|
||||
|
||||
@@ -432,12 +432,12 @@ gdk_registry_handle_global (void *data,
|
||||
display_wayland->subcompositor =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_subcompositor_interface, 1);
|
||||
}
|
||||
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0)
|
||||
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0 &&
|
||||
version == GDK_ZWP_POINTER_GESTURES_V1_VERSION)
|
||||
{
|
||||
display_wayland->pointer_gestures =
|
||||
wl_registry_bind (display_wayland->wl_registry,
|
||||
id, &zwp_pointer_gestures_v1_interface,
|
||||
MIN (version, GDK_ZWP_POINTER_GESTURES_V1_VERSION));
|
||||
id, &zwp_pointer_gestures_v1_interface, version);
|
||||
}
|
||||
else if (strcmp (interface, "zwp_primary_selection_device_manager_v1") == 0)
|
||||
{
|
||||
@@ -969,7 +969,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
display_class->create_surface = _gdk_wayland_display_create_surface;
|
||||
display_class->get_keymap = _gdk_wayland_display_get_keymap;
|
||||
|
||||
display_class->init_gl = gdk_wayland_display_init_gl;
|
||||
display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current;
|
||||
|
||||
display_class->get_monitors = gdk_wayland_display_get_monitors;
|
||||
display_class->get_monitor_at_surface = gdk_wayland_display_get_monitor_at_surface;
|
||||
@@ -991,26 +991,6 @@ gdk_wayland_display_get_toplevel_surfaces (GdkDisplay *display)
|
||||
return GDK_WAYLAND_DISPLAY (display)->toplevels;
|
||||
}
|
||||
|
||||
static struct wl_cursor_theme *
|
||||
try_load_theme (GdkWaylandDisplay *display_wayland,
|
||||
const char *dir,
|
||||
gboolean dotdir,
|
||||
const char *name,
|
||||
int size)
|
||||
{
|
||||
struct wl_cursor_theme *theme = NULL;
|
||||
char *path;
|
||||
|
||||
path = g_build_filename (dir, dotdir ? ".icons" : "icons", name, "cursors", NULL);
|
||||
|
||||
if (g_file_test (path, G_FILE_TEST_IS_DIR))
|
||||
theme = wl_cursor_theme_create (path, size, display_wayland->shm);
|
||||
|
||||
g_free (path);
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
static struct wl_cursor_theme *
|
||||
get_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||
const char *name,
|
||||
@@ -1020,18 +1000,16 @@ get_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_cursor_theme *theme = NULL;
|
||||
int i;
|
||||
|
||||
theme = try_load_theme (display_wayland, g_get_user_data_dir (), FALSE, name, size);
|
||||
if (theme)
|
||||
return theme;
|
||||
|
||||
theme = try_load_theme (display_wayland, g_get_home_dir (), TRUE, name, size);
|
||||
if (theme)
|
||||
return theme;
|
||||
|
||||
xdg_data_dirs = g_get_system_data_dirs ();
|
||||
for (i = 0; xdg_data_dirs[i]; i++)
|
||||
{
|
||||
theme = try_load_theme (display_wayland, xdg_data_dirs[i], FALSE, name, size);
|
||||
char *path = g_build_filename (xdg_data_dirs[i], "icons", name, "cursors", NULL);
|
||||
|
||||
if (g_file_test (path, G_FILE_TEST_IS_DIR))
|
||||
theme = wl_cursor_theme_create (path, size, display_wayland->shm);
|
||||
|
||||
g_free (path);
|
||||
|
||||
if (theme)
|
||||
return theme;
|
||||
}
|
||||
@@ -1670,7 +1648,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 } },
|
||||
/* 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 } },
|
||||
};
|
||||
|
||||
|
||||
@@ -153,12 +153,14 @@ struct _GdkWaylandDisplay
|
||||
|
||||
/* egl info */
|
||||
EGLDisplay egl_display;
|
||||
EGLConfig egl_config;
|
||||
int egl_major_version;
|
||||
int egl_minor_version;
|
||||
|
||||
guint have_egl : 1;
|
||||
guint have_egl_khr_create_context : 1;
|
||||
guint have_egl_buffer_age : 1;
|
||||
guint have_egl_swap_buffers_with_damage : 1;
|
||||
guint have_egl_surfaceless_context : 1;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDisplayClass
|
||||
|
||||
@@ -163,7 +163,6 @@ gdk_wayland_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
gdk_drag_set_cursor (drag, NULL);
|
||||
gdk_drag_drop_done (drag, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -291,7 +290,6 @@ data_source_dnd_finished (void *data,
|
||||
GdkDrag *drag = data;
|
||||
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkglcontext-wayland.h"
|
||||
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdksurface-wayland.h"
|
||||
|
||||
#include "gdkwaylanddisplay.h"
|
||||
#include "gdkwaylandglcontext.h"
|
||||
@@ -55,14 +53,14 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
||||
{
|
||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
GdkGLContext *share = gdk_gl_context_get_shared_context (context);
|
||||
GdkGLContext *shared_data_context = gdk_surface_get_shared_data_gl_context (gdk_gl_context_get_surface (context));
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLContext ctx;
|
||||
EGLint context_attribs[N_EGL_ATTRS];
|
||||
int major, minor, flags;
|
||||
gboolean debug_bit, forward_bit, legacy_bit, use_es;
|
||||
int i = 0;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||
@@ -122,9 +120,10 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
||||
use_es ? "yes" : "no"));
|
||||
|
||||
ctx = eglCreateContext (display_wayland->egl_display,
|
||||
display_wayland->egl_config,
|
||||
context_wayland->egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
|
||||
/* If context creation failed without the ES bit, let's try again with it */
|
||||
@@ -148,9 +147,10 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("eglCreateContext failed, switching to OpenGL ES"));
|
||||
ctx = eglCreateContext (display_wayland->egl_display,
|
||||
display_wayland->egl_config,
|
||||
context_wayland->egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
}
|
||||
|
||||
@@ -177,9 +177,10 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("eglCreateContext failed, switching to legacy"));
|
||||
ctx = eglCreateContext (display_wayland->egl_display,
|
||||
display_wayland->egl_config,
|
||||
context_wayland->egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
}
|
||||
|
||||
@@ -198,8 +199,6 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
gdk_gl_context_set_use_es (context, use_es);
|
||||
|
||||
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -214,8 +213,17 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context)
|
||||
|
||||
if (display_wayland->have_egl_buffer_age)
|
||||
{
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface);
|
||||
gdk_gl_context_make_current (context);
|
||||
GdkGLContext *shared;
|
||||
GdkWaylandGLContext *shared_wayland;
|
||||
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
if (shared == NULL)
|
||||
shared = context;
|
||||
shared_wayland = GDK_WAYLAND_GL_CONTEXT (shared);
|
||||
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface,
|
||||
shared_wayland->egl_config);
|
||||
gdk_gl_context_make_current (shared);
|
||||
eglQuerySurface (display_wayland->egl_display, egl_surface,
|
||||
EGL_BUFFER_AGE_EXT, &buffer_age);
|
||||
|
||||
@@ -248,47 +256,6 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context)
|
||||
return GDK_GL_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->get_damage (context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_gl_context_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
return eglMakeCurrent (display_wayland->egl_display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (!surfaceless)
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (gdk_gl_context_get_surface (context));
|
||||
else
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
|
||||
return eglMakeCurrent (display_wayland->egl_display,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_wayland->egl_context);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->begin_frame (draw_context, region);
|
||||
|
||||
glDrawBuffers (1, (GLenum[1]) { GL_BACK });
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
@@ -297,13 +264,18 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
||||
if (gdk_gl_context_get_shared_context (context))
|
||||
return;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface);
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface,
|
||||
context_wayland->egl_config);
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
@@ -350,12 +322,9 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||
|
||||
gobject_class->dispose = gdk_wayland_gl_context_dispose;
|
||||
|
||||
draw_context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_wayland_gl_context_end_frame;
|
||||
|
||||
context_class->realize = gdk_wayland_gl_context_realize;
|
||||
context_class->make_current = gdk_wayland_gl_context_make_current;
|
||||
context_class->clear_current = gdk_wayland_gl_context_clear_current;
|
||||
context_class->get_damage = gdk_wayland_gl_context_get_damage;
|
||||
}
|
||||
|
||||
@@ -371,8 +340,6 @@ gdk_wayland_gl_context_init (GdkWaylandGLContext *self)
|
||||
* Retrieves the EGL display connection object for the given GDK display.
|
||||
*
|
||||
* Returns: (nullable): the EGL display
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
gpointer
|
||||
gdk_wayland_display_get_egl_display (GdkDisplay *display)
|
||||
@@ -381,7 +348,7 @@ gdk_wayland_display_get_egl_display (GdkDisplay *display)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), NULL);
|
||||
|
||||
if (!gdk_display_prepare_gl (display, NULL))
|
||||
if (!gdk_wayland_display_init_gl (display))
|
||||
return NULL;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
@@ -426,11 +393,71 @@ out:
|
||||
return dpy;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_display_init_gl (GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLint major, minor;
|
||||
EGLDisplay dpy;
|
||||
|
||||
if (display_wayland->have_egl)
|
||||
return TRUE;
|
||||
|
||||
dpy = get_egl_display (display_wayland);
|
||||
|
||||
if (dpy == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!eglInitialize (dpy, &major, &minor))
|
||||
return FALSE;
|
||||
|
||||
if (!eglBindAPI (EGL_OPENGL_API))
|
||||
return FALSE;
|
||||
|
||||
display_wayland->egl_display = dpy;
|
||||
display_wayland->egl_major_version = major;
|
||||
display_wayland->egl_minor_version = minor;
|
||||
|
||||
display_wayland->have_egl = TRUE;
|
||||
|
||||
display_wayland->have_egl_khr_create_context =
|
||||
epoxy_has_egl_extension (dpy, "EGL_KHR_create_context");
|
||||
|
||||
display_wayland->have_egl_buffer_age =
|
||||
epoxy_has_egl_extension (dpy, "EGL_EXT_buffer_age");
|
||||
|
||||
display_wayland->have_egl_swap_buffers_with_damage =
|
||||
epoxy_has_egl_extension (dpy, "EGL_EXT_swap_buffers_with_damage");
|
||||
|
||||
display_wayland->have_egl_surfaceless_context =
|
||||
epoxy_has_egl_extension (dpy, "EGL_KHR_surfaceless_context");
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("EGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
" - Version: %s\n"
|
||||
" - Client APIs: %s\n"
|
||||
" - Extensions:\n"
|
||||
"\t%s",
|
||||
display_wayland->egl_major_version,
|
||||
display_wayland->egl_minor_version,
|
||||
eglQueryString (dpy, EGL_VENDOR),
|
||||
eglQueryString (dpy, EGL_VERSION),
|
||||
eglQueryString (dpy, EGL_CLIENT_APIS),
|
||||
eglQueryString (dpy, EGL_EXTENSIONS)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define MAX_EGL_ATTRS 30
|
||||
|
||||
static EGLConfig
|
||||
get_eglconfig (EGLDisplay dpy)
|
||||
static gboolean
|
||||
find_eglconfig_for_surface (GdkSurface *surface,
|
||||
EGLConfig *egl_config_out,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig config;
|
||||
@@ -455,129 +482,59 @@ get_eglconfig (EGLDisplay dpy)
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
/* Pick first valid configuration i guess? */
|
||||
if (!eglChooseConfig (dpy, attrs, &config, 1, &count) || count < 1)
|
||||
return NULL;
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, &config, 1, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return config;
|
||||
g_assert (egl_config_out);
|
||||
*egl_config_out = config;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef MAX_EGL_ATTRS
|
||||
|
||||
GdkGLContext *
|
||||
gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
gdk_wayland_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLint major, minor;
|
||||
EGLDisplay dpy;
|
||||
GdkGLContext *ctx;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
G_GNUC_UNUSED gint64 start_time2;
|
||||
GdkWaylandGLContext *context;
|
||||
EGLConfig config;
|
||||
|
||||
start_time2 = GDK_PROFILER_CURRENT_TIME;
|
||||
dpy = get_egl_display (display_wayland);
|
||||
gdk_profiler_end_mark (start_time, "get_egl_display", NULL);
|
||||
if (dpy == NULL)
|
||||
if (!gdk_wayland_display_init_gl (display))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Failed to create EGL display"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
start_time2 = GDK_PROFILER_CURRENT_TIME;
|
||||
if (!eglInitialize (dpy, &major, &minor))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Could not initialize EGL display"));
|
||||
return NULL;
|
||||
}
|
||||
gdk_profiler_end_mark (start_time2, "eglInitialize", NULL);
|
||||
|
||||
if (major < GDK_EGL_MIN_VERSION_MAJOR ||
|
||||
(major == GDK_EGL_MIN_VERSION_MAJOR && minor < GDK_EGL_MIN_VERSION_MINOR))
|
||||
{
|
||||
eglTerminate (dpy);
|
||||
g_set_error (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("EGL version %d.%d is too old. GTK requires %d.%d"),
|
||||
major, minor, GDK_EGL_MIN_VERSION_MAJOR, GDK_EGL_MIN_VERSION_MINOR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
start_time2 = GDK_PROFILER_CURRENT_TIME;
|
||||
if (!eglBindAPI (EGL_OPENGL_API))
|
||||
{
|
||||
eglTerminate (dpy);
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No GL implementation is available"));
|
||||
return NULL;
|
||||
}
|
||||
gdk_profiler_end_mark (start_time2, "eglBindAPI", NULL);
|
||||
|
||||
if (!epoxy_has_egl_extension (dpy, "EGL_KHR_create_context"))
|
||||
if (!display_wayland->have_egl_khr_create_context)
|
||||
{
|
||||
eglTerminate (dpy);
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
|
||||
_("Core GL is not available on EGL implementation"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!epoxy_has_egl_extension (dpy, "EGL_KHR_surfaceless_context"))
|
||||
{
|
||||
eglTerminate (dpy);
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
|
||||
_("Surfaceless contexts are not supported on this EGL implementation"));
|
||||
return NULL;
|
||||
}
|
||||
if (!find_eglconfig_for_surface (surface, &config, error))
|
||||
return NULL;
|
||||
|
||||
start_time2 = GDK_PROFILER_CURRENT_TIME;
|
||||
display_wayland->egl_config = get_eglconfig (dpy);
|
||||
gdk_profiler_end_mark (start_time2, "get_eglconfig", NULL);
|
||||
if (!display_wayland->egl_config)
|
||||
{
|
||||
eglTerminate (dpy);
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return NULL;
|
||||
}
|
||||
context = g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
|
||||
"surface", surface,
|
||||
"shared-context", share,
|
||||
NULL);
|
||||
|
||||
display_wayland->egl_display = dpy;
|
||||
display_wayland->egl_major_version = major;
|
||||
display_wayland->egl_minor_version = minor;
|
||||
context->egl_config = config;
|
||||
context->is_attached = attached;
|
||||
|
||||
display_wayland->have_egl_buffer_age =
|
||||
epoxy_has_egl_extension (dpy, "EGL_EXT_buffer_age");
|
||||
|
||||
display_wayland->have_egl_swap_buffers_with_damage =
|
||||
epoxy_has_egl_extension (dpy, "EGL_EXT_swap_buffers_with_damage");
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("EGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
" - Version: %s\n"
|
||||
" - Client APIs: %s\n"
|
||||
" - Extensions:\n"
|
||||
"\t%s",
|
||||
display_wayland->egl_major_version,
|
||||
display_wayland->egl_minor_version,
|
||||
eglQueryString (dpy, EGL_VENDOR),
|
||||
eglQueryString (dpy, EGL_VERSION),
|
||||
eglQueryString (dpy, EGL_CLIENT_APIS),
|
||||
eglQueryString (dpy, EGL_EXTENSIONS)));
|
||||
|
||||
ctx = g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
gdk_profiler_end_mark (start_time, "init Wayland GL", NULL);
|
||||
|
||||
return ctx;
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -606,3 +563,42 @@ gdk_wayland_gl_context_dispose (GObject *gobject)
|
||||
G_OBJECT_CLASS (gdk_wayland_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWaylandGLContext *context_wayland;
|
||||
GdkSurface *surface;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
eglMakeCurrent(display_wayland->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (context_wayland->is_attached || gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)))
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface, context_wayland->egl_config);
|
||||
else
|
||||
{
|
||||
if (display_wayland->have_egl_surfaceless_context)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = gdk_wayland_surface_get_dummy_egl_surface (surface,
|
||||
context_wayland->egl_config);
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent (display_wayland->egl_display, egl_surface,
|
||||
egl_surface, context_wayland->egl_context))
|
||||
{
|
||||
g_warning ("eglMakeCurrent failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ struct _GdkWaylandGLContext
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
EGLContext egl_context;
|
||||
EGLConfig egl_config;
|
||||
gboolean is_attached;
|
||||
};
|
||||
|
||||
struct _GdkWaylandGLContextClass
|
||||
@@ -43,8 +45,13 @@ struct _GdkWaylandGLContextClass
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
|
||||
GdkGLContext * gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||
gboolean gdk_wayland_display_init_gl (GdkDisplay *display);
|
||||
GdkGLContext * gdk_wayland_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attach,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -182,6 +182,11 @@ cairo_surface_t * _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *di
|
||||
struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface);
|
||||
gboolean _gdk_wayland_is_shm_surface (cairo_surface_t *surface);
|
||||
|
||||
EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config);
|
||||
EGLSurface gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config);
|
||||
|
||||
struct gtk_surface1 * gdk_wayland_surface_get_gtk_surface (GdkSurface *surface);
|
||||
|
||||
void gdk_wayland_seat_set_global_cursor (GdkSeat *seat,
|
||||
|
||||
@@ -103,6 +103,7 @@ struct _GdkWaylandSurface
|
||||
|
||||
struct gtk_surface1 *gtk_surface;
|
||||
struct wl_egl_window *egl_window;
|
||||
struct wl_egl_window *dummy_egl_window;
|
||||
struct zxdg_exported_v1 *xdg_exported;
|
||||
struct org_kde_kwin_server_decoration *server_decoration;
|
||||
} display_server;
|
||||
@@ -110,6 +111,7 @@ struct _GdkWaylandSurface
|
||||
struct wl_event_queue *event_queue;
|
||||
|
||||
EGLSurface egl_surface;
|
||||
EGLSurface dummy_egl_surface;
|
||||
|
||||
uint32_t reposition_token;
|
||||
uint32_t received_reposition_token;
|
||||
@@ -2899,6 +2901,18 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
|
||||
if (impl->display_server.wl_surface)
|
||||
{
|
||||
if (impl->dummy_egl_surface)
|
||||
{
|
||||
eglDestroySurface (display_wayland->egl_display, impl->dummy_egl_surface);
|
||||
impl->dummy_egl_surface = NULL;
|
||||
}
|
||||
|
||||
if (impl->display_server.dummy_egl_window)
|
||||
{
|
||||
wl_egl_window_destroy (impl->display_server.dummy_egl_window);
|
||||
impl->display_server.dummy_egl_window = NULL;
|
||||
}
|
||||
|
||||
if (impl->egl_surface)
|
||||
{
|
||||
eglDestroySurface (display_wayland->egl_display, impl->egl_surface);
|
||||
@@ -4224,6 +4238,7 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
|
||||
impl_class->drag_begin = _gdk_wayland_surface_drag_begin;
|
||||
impl_class->get_scale_factor = gdk_wayland_surface_get_scale_factor;
|
||||
impl_class->set_opaque_region = gdk_wayland_surface_set_opaque_region;
|
||||
impl_class->create_gl_context = gdk_wayland_surface_create_gl_context;
|
||||
impl_class->request_layout = gdk_wayland_surface_request_layout;
|
||||
impl_class->compute_size = gdk_wayland_surface_compute_size;
|
||||
}
|
||||
@@ -4289,7 +4304,8 @@ gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface)
|
||||
}
|
||||
|
||||
EGLSurface
|
||||
gdk_wayland_surface_get_egl_surface (GdkSurface *surface)
|
||||
gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkWaylandSurface *impl;
|
||||
@@ -4304,12 +4320,35 @@ gdk_wayland_surface_get_egl_surface (GdkSurface *surface)
|
||||
egl_window = gdk_wayland_surface_get_wl_egl_window (surface);
|
||||
|
||||
impl->egl_surface =
|
||||
eglCreateWindowSurface (display->egl_display, display->egl_config, egl_window, NULL);
|
||||
eglCreateWindowSurface (display->egl_display, config, egl_window, NULL);
|
||||
}
|
||||
|
||||
return impl->egl_surface;
|
||||
}
|
||||
|
||||
EGLSurface
|
||||
gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkWaylandSurface *impl;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
|
||||
|
||||
impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (impl->dummy_egl_surface == NULL)
|
||||
{
|
||||
impl->display_server.dummy_egl_window =
|
||||
wl_egl_window_create (impl->display_server.wl_surface, 1, 1);
|
||||
|
||||
impl->dummy_egl_surface =
|
||||
eglCreateWindowSurface (display->egl_display, config, impl->display_server.dummy_egl_window, NULL);
|
||||
}
|
||||
|
||||
return impl->dummy_egl_surface;
|
||||
}
|
||||
|
||||
struct gtk_surface1 *
|
||||
gdk_wayland_surface_get_gtk_surface (GdkSurface *surface)
|
||||
{
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
|
||||
#include "gdkwaylandsurface.h"
|
||||
|
||||
#include <wayland-egl.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel,
|
||||
@@ -41,6 +38,4 @@ void gdk_wayland_toplevel_announce_ssd (GdkTopl
|
||||
gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel);
|
||||
void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel);
|
||||
|
||||
EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -481,7 +481,6 @@ register_display_change_notification (GdkDisplay *display)
|
||||
wclass.lpszClassName = "GdkDisplayChange";
|
||||
wclass.lpfnWndProc = display_change_window_procedure;
|
||||
wclass.hInstance = _gdk_app_hmodule;
|
||||
wclass.style = CS_OWNDC;
|
||||
|
||||
klass = RegisterClass (&wclass);
|
||||
if (klass)
|
||||
@@ -657,13 +656,6 @@ gdk_win32_display_dispose (GObject *object)
|
||||
|
||||
if (display_win32->hwnd != NULL)
|
||||
{
|
||||
if (display_win32->dummy_context_wgl.hglrc != NULL)
|
||||
{
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
|
||||
display_win32->dummy_context_wgl.hglrc = NULL;
|
||||
}
|
||||
|
||||
DestroyWindow (display_win32->hwnd);
|
||||
display_win32->hwnd = NULL;
|
||||
}
|
||||
@@ -990,32 +982,31 @@ _gdk_win32_check_on_arm64 (GdkWin32Display *display)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_display_init (GdkWin32Display *display_win32)
|
||||
gdk_win32_display_init (GdkWin32Display *display)
|
||||
{
|
||||
const char *scale_str = g_getenv ("GDK_SCALE");
|
||||
|
||||
display_win32->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR));
|
||||
display->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR));
|
||||
|
||||
_gdk_win32_enable_hidpi (display_win32);
|
||||
_gdk_win32_check_on_arm64 (display_win32);
|
||||
_gdk_win32_enable_hidpi (display);
|
||||
_gdk_win32_check_on_arm64 (display);
|
||||
|
||||
/* if we have DPI awareness, set up fixed scale if set */
|
||||
if (display_win32->dpi_aware_type != PROCESS_DPI_UNAWARE &&
|
||||
if (display->dpi_aware_type != PROCESS_DPI_UNAWARE &&
|
||||
scale_str != NULL)
|
||||
{
|
||||
display_win32->surface_scale = atol (scale_str);
|
||||
display->surface_scale = atol (scale_str);
|
||||
|
||||
if (display_win32->surface_scale <= 0)
|
||||
display_win32->surface_scale = 1;
|
||||
if (display->surface_scale <= 0)
|
||||
display->surface_scale = 1;
|
||||
|
||||
display_win32->has_fixed_scale = TRUE;
|
||||
display->has_fixed_scale = TRUE;
|
||||
}
|
||||
else
|
||||
display_win32->surface_scale =
|
||||
gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
display->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display, NULL, NULL, NULL);
|
||||
|
||||
_gdk_win32_display_init_cursors (display_win32);
|
||||
gdk_win32_display_check_composited (display_win32);
|
||||
_gdk_win32_display_init_cursors (display);
|
||||
gdk_win32_display_check_composited (display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1066,64 +1057,64 @@ gdk_win32_display_get_monitors (GdkDisplay *display)
|
||||
}
|
||||
|
||||
guint
|
||||
gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
GdkSurface *surface,
|
||||
HMONITOR hmonitor)
|
||||
_gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
||||
HMONITOR hmonitor,
|
||||
HWND hwnd,
|
||||
int *dpi)
|
||||
{
|
||||
gboolean is_scale_acquired = FALSE;
|
||||
gboolean use_dpi_for_monitor = FALSE;
|
||||
guint dpix, dpiy;
|
||||
|
||||
if (display_win32->have_at_least_win81)
|
||||
if (win32_display->have_at_least_win81)
|
||||
{
|
||||
if (surface != NULL && hmonitor == NULL)
|
||||
hmonitor = MonitorFromWindow (GDK_SURFACE_HWND (surface),
|
||||
MONITOR_DEFAULTTONEAREST);
|
||||
if (hmonitor != NULL &&
|
||||
display_win32->shcore_funcs.hshcore != NULL &&
|
||||
display_win32->shcore_funcs.getDpiForMonitorFunc != NULL)
|
||||
if (hmonitor != NULL)
|
||||
use_dpi_for_monitor = TRUE;
|
||||
|
||||
else
|
||||
{
|
||||
if (hwnd != NULL)
|
||||
{
|
||||
hmonitor = MonitorFromWindow (hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
use_dpi_for_monitor = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (use_dpi_for_monitor)
|
||||
{
|
||||
/* Use GetDpiForMonitor() for Windows 8.1+, when we have a HMONITOR */
|
||||
if (display_win32->shcore_funcs.getDpiForMonitorFunc (hmonitor,
|
||||
MDT_EFFECTIVE_DPI,
|
||||
&dpix,
|
||||
&dpiy) == S_OK)
|
||||
is_scale_acquired = TRUE;
|
||||
if (win32_display->shcore_funcs.hshcore != NULL &&
|
||||
win32_display->shcore_funcs.getDpiForMonitorFunc != NULL)
|
||||
{
|
||||
if (win32_display->shcore_funcs.getDpiForMonitorFunc (hmonitor,
|
||||
MDT_EFFECTIVE_DPI,
|
||||
&dpix,
|
||||
&dpiy) == S_OK)
|
||||
{
|
||||
is_scale_acquired = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Go back to GetDeviceCaps() for Windows 8 and earlier, or when we don't
|
||||
* have a HMONITOR nor a HWND
|
||||
*/
|
||||
HDC hdc;
|
||||
|
||||
if (surface != NULL)
|
||||
{
|
||||
if (GDK_WIN32_SURFACE (surface)->hdc == NULL)
|
||||
GDK_WIN32_SURFACE (surface)->hdc = GetDC (GDK_SURFACE_HWND (surface));
|
||||
|
||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||
}
|
||||
else
|
||||
hdc = GetDC (NULL);
|
||||
HDC hdc = GetDC (hwnd);
|
||||
|
||||
/* in case we can't get the DC for the window, return 1 for the scale */
|
||||
if (hdc == NULL)
|
||||
return 1;
|
||||
{
|
||||
if (dpi != NULL)
|
||||
*dpi = USER_DEFAULT_SCREEN_DPI;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
dpix = GetDeviceCaps (hdc, LOGPIXELSX);
|
||||
dpiy = GetDeviceCaps (hdc, LOGPIXELSY);
|
||||
|
||||
/*
|
||||
* If surface is not NULL, the HDC should not be released, since surfaces have
|
||||
* Win32 windows created with CS_OWNDC
|
||||
*/
|
||||
if (surface == NULL)
|
||||
ReleaseDC (NULL, hdc);
|
||||
ReleaseDC (hwnd, hdc);
|
||||
|
||||
is_scale_acquired = TRUE;
|
||||
}
|
||||
@@ -1131,13 +1122,21 @@ gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
if (is_scale_acquired)
|
||||
/* USER_DEFAULT_SCREEN_DPI = 96, in winuser.h */
|
||||
{
|
||||
if (display_win32->has_fixed_scale)
|
||||
return display_win32->surface_scale;
|
||||
if (dpi != NULL)
|
||||
*dpi = dpix;
|
||||
|
||||
if (win32_display->has_fixed_scale)
|
||||
return win32_display->surface_scale;
|
||||
else
|
||||
return dpix / USER_DEFAULT_SCREEN_DPI > 1 ? dpix / USER_DEFAULT_SCREEN_DPI : 1;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
{
|
||||
if (dpi != NULL)
|
||||
*dpi = USER_DEFAULT_SCREEN_DPI;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1148,85 +1147,6 @@ gdk_win32_display_get_setting (GdkDisplay *display,
|
||||
return _gdk_win32_get_setting (name, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_display_init_gl_backend (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_EGL))
|
||||
return gdk_win32_display_init_egl (display, error);
|
||||
#endif
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_WGL))
|
||||
return gdk_win32_display_init_wgl (display, error);
|
||||
|
||||
/* No env vars set, do the regular GL initialization, first WGL and then EGL,
|
||||
* as WGL is the more tried-and-tested configuration.
|
||||
*/
|
||||
|
||||
if (gdk_win32_display_init_wgl (display, error))
|
||||
return TRUE;
|
||||
g_clear_error (error);
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (gdk_win32_display_init_egl (display, error))
|
||||
return TRUE;
|
||||
#endif
|
||||
g_clear_error (error);
|
||||
|
||||
return gdk_win32_display_init_wgl (display, error);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (display_win32->egl_disp)
|
||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL, "display", display, NULL);
|
||||
else
|
||||
#endif
|
||||
if (display_win32->wgl_pixel_format != 0)
|
||||
gl_context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL, "display", display, NULL);
|
||||
|
||||
g_return_val_if_fail (gl_context != NULL, NULL);
|
||||
|
||||
return gl_context;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_win32_display_get_egl_display:
|
||||
* @display: (type GdkWin32Display): a Win32 display
|
||||
*
|
||||
* Retrieves the EGL display connection object for the given GDK display.
|
||||
*
|
||||
* Returns: (nullable): the EGL display
|
||||
*/
|
||||
gpointer
|
||||
gdk_win32_display_get_egl_display (GdkDisplay *display)
|
||||
{
|
||||
GdkWin32Display *display_win32;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), NULL);
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
if (display_win32->wgl_pixel_format != 0)
|
||||
return NULL;
|
||||
|
||||
return display_win32->egl_disp;
|
||||
#else
|
||||
/* no EGL support */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
{
|
||||
@@ -1252,6 +1172,7 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
display_class->create_surface = _gdk_win32_display_create_surface;
|
||||
|
||||
display_class->get_keymap = _gdk_win32_display_get_keymap;
|
||||
display_class->make_gl_context_current = _gdk_win32_display_make_gl_context_current;
|
||||
|
||||
display_class->get_monitors = gdk_win32_display_get_monitors;
|
||||
|
||||
@@ -1262,7 +1183,6 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
|
||||
display_class->get_setting = gdk_win32_display_get_setting;
|
||||
display_class->set_cursor_theme = gdk_win32_display_set_cursor_theme;
|
||||
display_class->init_gl = gdk_win32_display_init_gl;
|
||||
|
||||
_gdk_win32_surfaceing_init ();
|
||||
}
|
||||
|
||||
@@ -106,12 +106,6 @@ typedef struct _GdkWin32KernelCPUFuncs
|
||||
funcIsWow64Process2 isWow64Process2;
|
||||
} GdkWin32KernelCPUFuncs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HDC hdc;
|
||||
HGLRC hglrc;
|
||||
} GdkWin32GLDummyContextWGL;
|
||||
|
||||
struct _GdkWin32Display
|
||||
{
|
||||
GdkDisplay display;
|
||||
@@ -125,15 +119,15 @@ struct _GdkWin32Display
|
||||
HWND hwnd;
|
||||
|
||||
/* WGL/OpenGL Items */
|
||||
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
||||
int wgl_pixel_format;
|
||||
guint have_wgl : 1;
|
||||
guint gl_version;
|
||||
HWND gl_hwnd;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
/* EGL (Angle) Items */
|
||||
guint have_egl : 1;
|
||||
guint egl_version;
|
||||
EGLDisplay egl_disp;
|
||||
EGLConfig egl_config;
|
||||
HDC hdc_egl_temp;
|
||||
#endif
|
||||
|
||||
@@ -191,9 +185,10 @@ GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
|
||||
|
||||
void gdk_win32_display_check_composited (GdkWin32Display *display);
|
||||
|
||||
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
GdkSurface *surface,
|
||||
HMONITOR hmonitor);
|
||||
guint _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
||||
HMONITOR hmonitor,
|
||||
HWND hwnd,
|
||||
int *dpi);
|
||||
|
||||
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
|
||||
|
||||
|
||||
@@ -793,7 +793,7 @@ gdk_drag_new (GdkDisplay *display,
|
||||
GdkDragProtocol protocol)
|
||||
{
|
||||
GdkWin32Drag *drag_win32;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||
GdkDrag *drag;
|
||||
|
||||
drag_win32 = g_object_new (GDK_TYPE_WIN32_DRAG,
|
||||
@@ -805,10 +805,10 @@ gdk_drag_new (GdkDisplay *display,
|
||||
|
||||
drag = GDK_DRAG (drag_win32);
|
||||
|
||||
if (display_win32->has_fixed_scale)
|
||||
drag_win32->scale = display_win32->surface_scale;
|
||||
if (win32_display->has_fixed_scale)
|
||||
drag_win32->scale = win32_display->surface_scale;
|
||||
else
|
||||
drag_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
drag_win32->scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, NULL, NULL, NULL);
|
||||
|
||||
drag_win32->protocol = protocol;
|
||||
|
||||
@@ -2345,8 +2345,8 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
|
||||
x_root = event->surface->x + x;
|
||||
y_root = event->surface->y + y;
|
||||
x_root = x + _gdk_offset_x;
|
||||
y_root = y + _gdk_offset_y;
|
||||
|
||||
if (drag_win32->drag_surface)
|
||||
move_drag_surface (drag, x_root, y_root);
|
||||
|
||||
@@ -177,7 +177,7 @@ gdk_drop_new (GdkDisplay *display,
|
||||
GdkDragProtocol protocol)
|
||||
{
|
||||
GdkWin32Drop *drop_win32;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
drop_win32 = g_object_new (GDK_TYPE_WIN32_DROP,
|
||||
"device", device,
|
||||
@@ -186,10 +186,10 @@ gdk_drop_new (GdkDisplay *display,
|
||||
"surface", surface,
|
||||
NULL);
|
||||
|
||||
if (display_win32->has_fixed_scale)
|
||||
drop_win32->scale = display_win32->surface_scale;
|
||||
if (win32_display->has_fixed_scale)
|
||||
drop_win32->scale = win32_display->surface_scale;
|
||||
else
|
||||
drop_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
drop_win32->scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, NULL, NULL, NULL);
|
||||
|
||||
drop_win32->protocol = protocol;
|
||||
|
||||
|
||||
@@ -2343,6 +2343,7 @@ gdk_event_translate (MSG *msg,
|
||||
current_root_x = (msg->pt.x + _gdk_offset_x) / impl->surface_scale;
|
||||
current_root_y = (msg->pt.y + _gdk_offset_y) / impl->surface_scale;
|
||||
|
||||
|
||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||
else if (_gdk_input_ignore_core == 0)
|
||||
|
||||
@@ -1,504 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* gdkglcontext-win32.c: Win32 specific OpenGL wrappers
|
||||
*
|
||||
* Copyright © 2014 Emmanuele Bassi
|
||||
* Copyright © 2014 Alexander Larsson
|
||||
* Copyright © 2014 Chun-wei Fan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkprivate-win32.h"
|
||||
#include "gdksurface-win32.h"
|
||||
#include "gdkglcontext-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
|
||||
#include "gdkwin32display.h"
|
||||
#include "gdkwin32glcontext.h"
|
||||
#include "gdkwin32misc.h"
|
||||
#include "gdkwin32screen.h"
|
||||
#include "gdkwin32surface.h"
|
||||
|
||||
#include "gdkglcontext.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
struct _GdkWin32GLContextEGL
|
||||
{
|
||||
GdkWin32GLContext parent_instance;
|
||||
|
||||
/* EGL (Angle) Context Items */
|
||||
EGLContext egl_context;
|
||||
guint do_frame_sync : 1;
|
||||
};
|
||||
|
||||
typedef struct _GdkWin32GLContextClass GdkWin32GLContextEGLClass;
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32GLContextEGL, gdk_win32_gl_context_egl, GDK_TYPE_WIN32_GL_CONTEXT)
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_dispose (GObject *gobject)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (gobject);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (display_win32 != NULL)
|
||||
{
|
||||
if (eglGetCurrentContext () == context_egl->egl_context)
|
||||
eglMakeCurrent(display_win32->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
|
||||
GDK_NOTE (OPENGL, g_message ("Destroying EGL (ANGLE) context"));
|
||||
|
||||
eglDestroyContext (display_win32->egl_disp,
|
||||
context_egl->egl_context);
|
||||
context_egl->egl_context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_win32_gl_context_egl_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_egl_force_redraw (GdkSurface *surface)
|
||||
{
|
||||
/* We only need to call gdk_window_invalidate_rect () if necessary */
|
||||
if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
return impl->egl_force_redraw_all;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_egl_force_redraw (GdkSurface *surface)
|
||||
{
|
||||
if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (impl->egl_force_redraw_all)
|
||||
impl->egl_force_redraw_all = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
|
||||
cairo_rectangle_int_t whole_window;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
whole_window =
|
||||
(GdkRectangle) { 0, 0,
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface)
|
||||
};
|
||||
|
||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
|
||||
|
||||
if (is_egl_force_redraw (surface))
|
||||
{
|
||||
GdkRectangle rect = {0, 0, gdk_surface_get_width (surface), gdk_surface_get_height (surface)};
|
||||
|
||||
/* We need to do gdk_window_invalidate_rect() so that we don't get glitches after maximizing or
|
||||
* restoring or using aerosnap
|
||||
*/
|
||||
gdk_surface_invalidate_rect (surface, &rect);
|
||||
reset_egl_force_redraw (surface);
|
||||
}
|
||||
|
||||
eglSwapBuffers (display_win32->egl_disp, egl_surface);
|
||||
}
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#endif
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_TYPE_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
|
||||
#endif
|
||||
|
||||
#ifndef EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
|
||||
#endif
|
||||
|
||||
static EGLDisplay
|
||||
gdk_win32_get_egl_display (GdkWin32Display *display)
|
||||
{
|
||||
EGLDisplay disp;
|
||||
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
|
||||
{
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
|
||||
if (getPlatformDisplay)
|
||||
{
|
||||
EGLint disp_attr[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE};
|
||||
|
||||
disp = getPlatformDisplay (EGL_PLATFORM_ANGLE_ANGLE, display->hdc_egl_temp, disp_attr);
|
||||
|
||||
if (disp != EGL_NO_DISPLAY)
|
||||
return disp;
|
||||
}
|
||||
}
|
||||
|
||||
return eglGetDisplay (display->hdc_egl_temp);
|
||||
}
|
||||
|
||||
#define MAX_EGL_ATTRS 30
|
||||
|
||||
static gboolean
|
||||
find_eglconfig_for_window (GdkWin32Display *display,
|
||||
EGLConfig *egl_config_out,
|
||||
EGLint *min_swap_interval_out,
|
||||
GError **error)
|
||||
{
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig *configs, chosen_config;
|
||||
|
||||
int i = 0;
|
||||
|
||||
EGLDisplay egl_disp = display->egl_disp;
|
||||
|
||||
attrs[i++] = EGL_CONFORMANT;
|
||||
attrs[i++] = EGL_OPENGL_ES2_BIT;
|
||||
attrs[i++] = EGL_SURFACE_TYPE;
|
||||
attrs[i++] = EGL_WINDOW_BIT;
|
||||
|
||||
attrs[i++] = EGL_COLOR_BUFFER_TYPE;
|
||||
attrs[i++] = EGL_RGB_BUFFER;
|
||||
|
||||
attrs[i++] = EGL_RED_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = EGL_GREEN_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = EGL_BLUE_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = EGL_ALPHA_SIZE;
|
||||
attrs[i++] = 1;
|
||||
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
if (!eglChooseConfig (display->egl_disp, attrs, NULL, 0, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
configs = g_new (EGLConfig, count);
|
||||
|
||||
if (!eglChooseConfig (display->egl_disp, attrs, configs, count, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Pick first valid configuration i guess? */
|
||||
chosen_config = configs[0];
|
||||
|
||||
if (!eglGetConfigAttrib (display->egl_disp, chosen_config,
|
||||
EGL_MIN_SWAP_INTERVAL, min_swap_interval_out))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
"Could not retrieve the minimum swap interval");
|
||||
g_free (configs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (egl_config_out != NULL)
|
||||
*egl_config_out = chosen_config;
|
||||
|
||||
g_free (configs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_win32_display_init_egl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
int best_idx = 0;
|
||||
EGLDisplay egl_disp;
|
||||
|
||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||
return TRUE;
|
||||
|
||||
egl_disp = gdk_win32_get_egl_display (display_win32);
|
||||
|
||||
if (egl_disp == EGL_NO_DISPLAY)
|
||||
return FALSE;
|
||||
|
||||
if (!eglInitialize (egl_disp, NULL, NULL))
|
||||
{
|
||||
eglTerminate (egl_disp);
|
||||
egl_disp = EGL_NO_DISPLAY;
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No GL implementation is available"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display_win32->egl_disp = egl_disp;
|
||||
display_win32->egl_version = epoxy_egl_version (egl_disp);
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
display_win32->hasEglSurfacelessContext =
|
||||
epoxy_has_egl_extension (egl_disp, "EGL_KHR_surfaceless_context");
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("EGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
" - Checked extensions:\n"
|
||||
"\t* EGL_KHR_surfaceless_context: %s\n",
|
||||
display_win32->egl_version / 10,
|
||||
display_win32->egl_version % 10,
|
||||
eglQueryString (display_win32->egl_disp, EGL_VENDOR),
|
||||
display_win32->hasEglSurfacelessContext ? "yes" : "no"));
|
||||
|
||||
return find_eglconfig_for_window (display_win32, &display_win32->egl_config,
|
||||
&display_win32->egl_min_swap_interval, error);
|
||||
}
|
||||
|
||||
#define N_EGL_ATTRS 16
|
||||
|
||||
static EGLContext
|
||||
create_egl_context (EGLDisplay display,
|
||||
EGLConfig config,
|
||||
GdkGLContext *share,
|
||||
int flags,
|
||||
int major,
|
||||
int minor,
|
||||
gboolean *is_legacy)
|
||||
{
|
||||
EGLContext ctx;
|
||||
EGLint context_attribs[N_EGL_ATTRS];
|
||||
int i = 0;
|
||||
|
||||
/* ANGLE does not support the GL_OES_vertex_array_object extension, so we need to use ES3 directly */
|
||||
context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
context_attribs[i++] = 3;
|
||||
|
||||
/* Specify the flags */
|
||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||
context_attribs[i++] = flags;
|
||||
|
||||
context_attribs[i++] = EGL_NONE;
|
||||
g_assert (i < N_EGL_ATTRS);
|
||||
|
||||
ctx = eglCreateContext (display,
|
||||
config,
|
||||
share != NULL ? GDK_WIN32_GL_CONTEXT_EGL (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
|
||||
if (ctx != EGL_NO_CONTEXT)
|
||||
GDK_NOTE (OPENGL, g_message ("Created EGL context[%p]", ctx));
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_egl_realize (GdkGLContext *context,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||
|
||||
gboolean debug_bit, compat_bit, legacy_bit;
|
||||
gboolean use_es = FALSE;
|
||||
EGLContext egl_context;
|
||||
EGLContext ctx;
|
||||
|
||||
/* request flags and specific versions for core (3.2+) WGL context */
|
||||
int flags = 0;
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* A legacy context cannot be shared with core profile ones, so this means we
|
||||
* must stick to a legacy context if the shared context is a legacy context
|
||||
*/
|
||||
|
||||
/* if GDK_GL_LEGACY is set, we default to a legacy context */
|
||||
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ?
|
||||
TRUE :
|
||||
share != NULL && gdk_gl_context_is_legacy (share);
|
||||
|
||||
use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
||||
(share != NULL && gdk_gl_context_get_use_es (share));
|
||||
|
||||
if (debug_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
||||
if (compat_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||
|
||||
GDK_NOTE (OPENGL, g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s)",
|
||||
major, minor,
|
||||
debug_bit ? "yes" : "no",
|
||||
compat_bit ? "yes" : "no",
|
||||
legacy_bit ? "yes" : "no"));
|
||||
|
||||
ctx = create_egl_context (display_win32->egl_disp,
|
||||
display_win32->egl_config,
|
||||
share,
|
||||
flags,
|
||||
major,
|
||||
minor,
|
||||
&legacy_bit);
|
||||
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDK_NOTE (OPENGL, g_print ("Created EGL context[%p]\n", ctx));
|
||||
|
||||
context_egl->egl_context = ctx;
|
||||
|
||||
/* We are using GLES here */
|
||||
gdk_gl_context_set_use_es (context, TRUE);
|
||||
|
||||
/* Ensure that any other context is created with a legacy bit set */
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_egl_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||
return eglMakeCurrent (display_win32->egl_disp,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_egl_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
EGLSurface egl_surface;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (!surfaceless)
|
||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, FALSE);
|
||||
else
|
||||
{
|
||||
if (display_win32->hasEglSurfacelessContext)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = gdk_win32_surface_get_egl_surface (surface, display_win32->egl_config, TRUE);
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent (display_win32->egl_disp,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_egl->egl_context))
|
||||
return FALSE;
|
||||
|
||||
if (display_win32->egl_min_swap_interval == 0)
|
||||
eglSwapInterval (display_win32->egl_disp, 0);
|
||||
else
|
||||
g_debug ("Can't disable GL swap interval");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *update_area)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
gdk_win32_surface_handle_queued_move_resize (draw_context);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->begin_frame (draw_context, update_area);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
|
||||
{
|
||||
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS(klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
context_class->realize = gdk_win32_gl_context_egl_realize;
|
||||
context_class->make_current = gdk_win32_gl_context_egl_make_current;
|
||||
context_class->clear_current = gdk_win32_gl_context_egl_clear_current;
|
||||
|
||||
draw_context_class->begin_frame = gdk_win32_gl_context_egl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_win32_gl_context_egl_end_frame;
|
||||
|
||||
gobject_class->dispose = gdk_win32_gl_context_egl_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_init (GdkWin32GLContextEGL *egl_context)
|
||||
{
|
||||
}
|
||||
@@ -1,727 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* gdkglcontext-win32.c: Win32 specific OpenGL wrappers
|
||||
*
|
||||
* Copyright © 2014 Emmanuele Bassi
|
||||
* Copyright © 2014 Alexander Larsson
|
||||
* Copyright © 2014 Chun-wei Fan
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkprivate-win32.h"
|
||||
#include "gdksurface-win32.h"
|
||||
#include "gdkglcontext-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
|
||||
#include "gdkwin32display.h"
|
||||
#include "gdkwin32glcontext.h"
|
||||
#include "gdkwin32misc.h"
|
||||
#include "gdkwin32screen.h"
|
||||
#include "gdkwin32surface.h"
|
||||
|
||||
#include "gdkglcontext.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdksurface.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <epoxy/wgl.h>
|
||||
|
||||
struct _GdkWin32GLContextWGL
|
||||
{
|
||||
GdkWin32GLContext parent_instance;
|
||||
|
||||
HGLRC wgl_context;
|
||||
guint do_frame_sync : 1;
|
||||
};
|
||||
|
||||
typedef struct _GdkWin32GLContextClass GdkWin32GLContextWGLClass;
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32GLContextWGL, gdk_win32_gl_context_wgl, GDK_TYPE_WIN32_GL_CONTEXT)
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_wgl_dispose (GObject *gobject)
|
||||
{
|
||||
GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (gobject);
|
||||
|
||||
if (context_wgl->wgl_context != NULL)
|
||||
{
|
||||
if (wglGetCurrentContext () == context_wgl->wgl_context)
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
|
||||
GDK_NOTE (OPENGL, g_print ("Destroying WGL context\n"));
|
||||
|
||||
wglDeleteContext (context_wgl->wgl_context);
|
||||
context_wgl->wgl_context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_win32_gl_context_wgl_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_wgl_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkWin32Display *display_win32 = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context)));
|
||||
cairo_rectangle_int_t whole_window;
|
||||
gboolean can_wait = display_win32->hasWglOMLSyncControl;
|
||||
HDC hdc;
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_wgl_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
whole_window = (GdkRectangle) { 0, 0, gdk_surface_get_width (surface), gdk_surface_get_height (surface) };
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "win32", "swap buffers");
|
||||
|
||||
if (surface != NULL)
|
||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||
else
|
||||
hdc = display_win32->dummy_context_wgl.hdc;
|
||||
|
||||
if (context_wgl->do_frame_sync)
|
||||
{
|
||||
|
||||
glFinish ();
|
||||
|
||||
if (can_wait)
|
||||
{
|
||||
gint64 ust, msc, sbc;
|
||||
|
||||
wglGetSyncValuesOML (hdc, &ust, &msc, &sbc);
|
||||
wglWaitForMscOML (hdc,
|
||||
0,
|
||||
2,
|
||||
(msc + 1) % 2,
|
||||
&ust, &msc, &sbc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SwapBuffers (hdc);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_wgl_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *update_area)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
gdk_win32_surface_handle_queued_move_resize (draw_context);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_wgl_parent_class)->begin_frame (draw_context, update_area);
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_init_dummy_wgl_context (GdkWin32Display *display_win32);
|
||||
|
||||
#define PIXEL_ATTRIBUTES 17
|
||||
|
||||
static int
|
||||
get_wgl_pfd (HDC hdc,
|
||||
PIXELFORMATDESCRIPTOR *pfd,
|
||||
GdkWin32Display *display_win32)
|
||||
{
|
||||
int best_pf = 0;
|
||||
|
||||
pfd->nSize = sizeof (PIXELFORMATDESCRIPTOR);
|
||||
|
||||
if (display_win32 != NULL && display_win32->hasWglARBPixelFormat)
|
||||
{
|
||||
UINT num_formats;
|
||||
int colorbits = GetDeviceCaps (hdc, BITSPIXEL);
|
||||
int i = 0;
|
||||
int pixelAttribs[PIXEL_ATTRIBUTES];
|
||||
|
||||
/* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here */
|
||||
HDC hdc_current = wglGetCurrentDC ();
|
||||
HGLRC hglrc_current = wglGetCurrentContext ();
|
||||
|
||||
/* Update PIXEL_ATTRIBUTES above if any groups are added here! */
|
||||
pixelAttribs[i] = WGL_DRAW_TO_WINDOW_ARB;
|
||||
pixelAttribs[i++] = GL_TRUE;
|
||||
|
||||
pixelAttribs[i++] = WGL_SUPPORT_OPENGL_ARB;
|
||||
pixelAttribs[i++] = GL_TRUE;
|
||||
|
||||
pixelAttribs[i++] = WGL_DOUBLE_BUFFER_ARB;
|
||||
pixelAttribs[i++] = GL_TRUE;
|
||||
|
||||
pixelAttribs[i++] = WGL_ACCELERATION_ARB;
|
||||
pixelAttribs[i++] = WGL_FULL_ACCELERATION_ARB;
|
||||
|
||||
pixelAttribs[i++] = WGL_PIXEL_TYPE_ARB;
|
||||
pixelAttribs[i++] = WGL_TYPE_RGBA_ARB;
|
||||
|
||||
pixelAttribs[i++] = WGL_COLOR_BITS_ARB;
|
||||
pixelAttribs[i++] = colorbits;
|
||||
|
||||
/* end of "Update PIXEL_ATTRIBUTES above if any groups are added here!" */
|
||||
|
||||
if (display_win32->hasWglARBmultisample)
|
||||
{
|
||||
pixelAttribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
|
||||
pixelAttribs[i++] = 1;
|
||||
|
||||
pixelAttribs[i++] = WGL_SAMPLES_ARB;
|
||||
pixelAttribs[i++] = 8;
|
||||
}
|
||||
|
||||
pixelAttribs[i++] = 0; /* end of pixelAttribs */
|
||||
best_pf = gdk_init_dummy_wgl_context (display_win32);
|
||||
|
||||
if (!wglMakeCurrent (display_win32->dummy_context_wgl.hdc,
|
||||
display_win32->dummy_context_wgl.hglrc))
|
||||
{
|
||||
wglMakeCurrent (hdc_current, hglrc_current);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wglChoosePixelFormatARB (hdc,
|
||||
pixelAttribs,
|
||||
NULL,
|
||||
1,
|
||||
&best_pf,
|
||||
&num_formats);
|
||||
|
||||
/* Go back to the HDC that we were using, since we are done with the dummy HDC and GL Context */
|
||||
wglMakeCurrent (hdc_current, hglrc_current);
|
||||
}
|
||||
else
|
||||
{
|
||||
pfd->nVersion = 1;
|
||||
pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
|
||||
pfd->iPixelType = PFD_TYPE_RGBA;
|
||||
pfd->cColorBits = GetDeviceCaps (hdc, BITSPIXEL);
|
||||
pfd->cAlphaBits = 8;
|
||||
pfd->dwLayerMask = PFD_MAIN_PLANE;
|
||||
|
||||
best_pf = ChoosePixelFormat (hdc, pfd);
|
||||
}
|
||||
|
||||
return best_pf;
|
||||
}
|
||||
|
||||
/* in WGL, for many OpenGL items, we need a dummy WGL context, so create
|
||||
* one and cache it for later use
|
||||
*/
|
||||
static int
|
||||
gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
gboolean set_pixel_format_result = FALSE;
|
||||
int best_idx = 0;
|
||||
|
||||
if (display_win32->dummy_context_wgl.hdc == NULL)
|
||||
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
|
||||
|
||||
memset (&pfd, 0, sizeof (PIXELFORMATDESCRIPTOR));
|
||||
|
||||
best_idx = get_wgl_pfd (display_win32->dummy_context_wgl.hdc, &pfd, NULL);
|
||||
|
||||
if (best_idx != 0)
|
||||
set_pixel_format_result = SetPixelFormat (display_win32->dummy_context_wgl.hdc,
|
||||
best_idx,
|
||||
&pfd);
|
||||
|
||||
if (best_idx == 0 || !set_pixel_format_result)
|
||||
return 0;
|
||||
|
||||
display_win32->dummy_context_wgl.hglrc =
|
||||
wglCreateContext (display_win32->dummy_context_wgl.hdc);
|
||||
|
||||
if (display_win32->dummy_context_wgl.hglrc == NULL)
|
||||
return 0;
|
||||
|
||||
return best_idx;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
int best_idx = 0;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
HDC hdc;
|
||||
|
||||
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
|
||||
*/
|
||||
best_idx = gdk_init_dummy_wgl_context (display_win32);
|
||||
hdc = display_win32->dummy_context_wgl.hdc;
|
||||
|
||||
if (best_idx == 0 ||
|
||||
!wglMakeCurrent (hdc, display_win32->dummy_context_wgl.hglrc))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No GL implementation is available"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display_win32->wgl_pixel_format = best_idx;
|
||||
display_win32->gl_version = epoxy_gl_version ();
|
||||
|
||||
display_win32->hasWglARBCreateContext =
|
||||
epoxy_has_wgl_extension (hdc, "WGL_ARB_create_context");
|
||||
display_win32->hasWglEXTSwapControl =
|
||||
epoxy_has_wgl_extension (hdc, "WGL_EXT_swap_control");
|
||||
display_win32->hasWglOMLSyncControl =
|
||||
epoxy_has_wgl_extension (hdc, "WGL_OML_sync_control");
|
||||
display_win32->hasWglARBPixelFormat =
|
||||
epoxy_has_wgl_extension (hdc, "WGL_ARB_pixel_format");
|
||||
display_win32->hasWglARBmultisample =
|
||||
epoxy_has_wgl_extension (hdc, "WGL_ARB_multisample");
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("WGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
" - Checked extensions:\n"
|
||||
"\t* WGL_ARB_pixel_format: %s\n"
|
||||
"\t* WGL_ARB_create_context: %s\n"
|
||||
"\t* WGL_EXT_swap_control: %s\n"
|
||||
"\t* WGL_OML_sync_control: %s\n"
|
||||
"\t* WGL_ARB_multisample: %s\n",
|
||||
display_win32->gl_version / 10,
|
||||
display_win32->gl_version % 10,
|
||||
glGetString (GL_VENDOR),
|
||||
display_win32->hasWglARBPixelFormat ? "yes" : "no",
|
||||
display_win32->hasWglARBCreateContext ? "yes" : "no",
|
||||
display_win32->hasWglEXTSwapControl ? "yes" : "no",
|
||||
display_win32->hasWglOMLSyncControl ? "yes" : "no",
|
||||
display_win32->hasWglARBmultisample ? "yes" : "no"));
|
||||
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Setup the legacy context after creating it */
|
||||
static gboolean
|
||||
ensure_legacy_wgl_context (HDC hdc,
|
||||
HGLRC hglrc_legacy,
|
||||
GdkGLContext *share)
|
||||
{
|
||||
GdkWin32GLContextWGL *context_wgl;
|
||||
|
||||
if (!wglMakeCurrent (hdc, hglrc_legacy))
|
||||
return FALSE;
|
||||
|
||||
if (share != NULL)
|
||||
{
|
||||
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
|
||||
|
||||
return wglShareLists (hglrc_legacy, context_wgl->wgl_context);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static HGLRC
|
||||
create_wgl_context_with_attribs (HDC hdc,
|
||||
HGLRC hglrc_base,
|
||||
GdkGLContext *share,
|
||||
int flags,
|
||||
int major,
|
||||
int minor,
|
||||
gboolean *is_legacy)
|
||||
{
|
||||
HGLRC hglrc;
|
||||
GdkWin32GLContextWGL *context_wgl;
|
||||
|
||||
/* if we have wglCreateContextAttribsARB(), create a
|
||||
* context with the compatibility profile if a legacy
|
||||
* context is requested, or when we go into fallback mode
|
||||
*/
|
||||
int profile = *is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
|
||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
|
||||
int attribs[] = {
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, profile,
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, *is_legacy ? 3 : major,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, *is_legacy ? 0 : minor,
|
||||
WGL_CONTEXT_FLAGS_ARB, flags,
|
||||
0
|
||||
};
|
||||
|
||||
if (share != NULL)
|
||||
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
|
||||
|
||||
hglrc = wglCreateContextAttribsARB (hdc,
|
||||
share != NULL ? context_wgl->wgl_context : NULL,
|
||||
attribs);
|
||||
|
||||
return hglrc;
|
||||
}
|
||||
|
||||
static HGLRC
|
||||
create_wgl_context (HDC hdc,
|
||||
GdkGLContext *share,
|
||||
int flags,
|
||||
int major,
|
||||
int minor,
|
||||
gboolean *is_legacy,
|
||||
gboolean hasWglARBCreateContext)
|
||||
{
|
||||
/* We need a legacy context for *all* cases */
|
||||
HGLRC hglrc_base = wglCreateContext (hdc);
|
||||
gboolean success = TRUE;
|
||||
|
||||
/* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here */
|
||||
HDC hdc_current = wglGetCurrentDC ();
|
||||
HGLRC hglrc_current = wglGetCurrentContext ();
|
||||
|
||||
/* if we have no wglCreateContextAttribsARB(), return the legacy context when all is set */
|
||||
if (*is_legacy && !hasWglARBCreateContext)
|
||||
{
|
||||
if (ensure_legacy_wgl_context (hdc, hglrc_base, share))
|
||||
{
|
||||
wglMakeCurrent (hdc_current, hglrc_current);
|
||||
return hglrc_base;
|
||||
}
|
||||
|
||||
success = FALSE;
|
||||
goto gl_fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
HGLRC hglrc = NULL;
|
||||
|
||||
if (!wglMakeCurrent (hdc, hglrc_base))
|
||||
{
|
||||
success = FALSE;
|
||||
goto gl_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
if (!(*is_legacy))
|
||||
{
|
||||
/* If we aren't using a legacy context in the beginning, try again with a compatibility profile 3.0 context */
|
||||
hglrc = create_wgl_context_with_attribs (hdc,
|
||||
hglrc_base,
|
||||
share,
|
||||
flags,
|
||||
0, 0,
|
||||
is_legacy);
|
||||
|
||||
*is_legacy = TRUE;
|
||||
}
|
||||
|
||||
if (hglrc == NULL)
|
||||
{
|
||||
if (!ensure_legacy_wgl_context (hdc, hglrc_base, share))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (success)
|
||||
GDK_NOTE (OPENGL, g_print ("Using legacy context as fallback\n"));
|
||||
}
|
||||
|
||||
gl_fail:
|
||||
|
||||
if (!success)
|
||||
{
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
wglDeleteContext (hglrc_base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wglMakeCurrent (hdc_current, hglrc_current);
|
||||
|
||||
if (hglrc != NULL)
|
||||
{
|
||||
wglDeleteContext (hglrc_base);
|
||||
return hglrc;
|
||||
}
|
||||
|
||||
return hglrc_base;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_wgl_pixformat_for_hdc (HDC hdc,
|
||||
int *best_idx,
|
||||
GdkWin32Display *display_win32)
|
||||
{
|
||||
gboolean already_checked = TRUE;
|
||||
*best_idx = GetPixelFormat (hdc);
|
||||
|
||||
/* one is only allowed to call SetPixelFormat(), and so ChoosePixelFormat()
|
||||
* one single time per window HDC
|
||||
*/
|
||||
if (*best_idx == 0)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
gboolean set_pixel_format_result = FALSE;
|
||||
|
||||
GDK_NOTE (OPENGL, g_print ("requesting pixel format...\n"));
|
||||
already_checked = FALSE;
|
||||
*best_idx = get_wgl_pfd (hdc, &pfd, display_win32);
|
||||
|
||||
if (*best_idx != 0)
|
||||
set_pixel_format_result = SetPixelFormat (hdc, *best_idx, &pfd);
|
||||
|
||||
/* ChoosePixelFormat() or SetPixelFormat() failed, bail out */
|
||||
if (*best_idx == 0 || !set_pixel_format_result)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDK_NOTE (OPENGL, g_print ("%s""requested and set pixel format: %d\n", already_checked ? "already " : "", *best_idx));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
|
||||
GError **error)
|
||||
{
|
||||
GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
|
||||
|
||||
gboolean debug_bit, compat_bit, legacy_bit;
|
||||
|
||||
/* request flags and specific versions for core (3.2+) WGL context */
|
||||
int flags = 0;
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
HGLRC hglrc;
|
||||
int pixel_format;
|
||||
HDC hdc;
|
||||
HWND hwnd;
|
||||
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
|
||||
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);
|
||||
|
||||
if (surface != NULL)
|
||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||
else
|
||||
hdc = display_win32->dummy_context_wgl.hdc;
|
||||
|
||||
/*
|
||||
* A legacy context cannot be shared with core profile ones, so this means we
|
||||
* must stick to a legacy context if the shared context is a legacy context
|
||||
*/
|
||||
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ?
|
||||
TRUE :
|
||||
share != NULL && gdk_gl_context_is_legacy (share);
|
||||
|
||||
if (!set_wgl_pixformat_for_hdc (hdc,
|
||||
&pixel_format,
|
||||
display_win32))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* if there isn't wglCreateContextAttribsARB() on WGL, use a legacy context */
|
||||
if (!legacy_bit)
|
||||
legacy_bit = !display_win32->hasWglARBCreateContext;
|
||||
if (debug_bit)
|
||||
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||
if (compat_bit)
|
||||
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s, legacy: %s)\n",
|
||||
compat_bit ? "core" : "compat",
|
||||
major,
|
||||
minor,
|
||||
debug_bit ? "yes" : "no",
|
||||
compat_bit ? "yes" : "no",
|
||||
legacy_bit ? "yes" : "no"));
|
||||
|
||||
hglrc = create_wgl_context (hdc,
|
||||
share,
|
||||
flags,
|
||||
major,
|
||||
minor,
|
||||
&legacy_bit,
|
||||
display_win32->hasWglARBCreateContext);
|
||||
|
||||
if (hglrc == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("Created WGL context[%p], pixel_format=%d\n",
|
||||
hglrc,
|
||||
pixel_format));
|
||||
|
||||
context_wgl->wgl_context = hglrc;
|
||||
|
||||
/* No GLES, WGL does not support using EGL contexts */
|
||||
gdk_gl_context_set_use_es (context, FALSE);
|
||||
|
||||
/* Ensure that any other context is created with a legacy bit set */
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_wgl_clear_current (GdkGLContext *context)
|
||||
{
|
||||
return wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_wgl_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkWin32GLContextWGL *context_wgl = GDK_WIN32_GL_CONTEXT_WGL (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
HDC hdc;
|
||||
|
||||
if (surfaceless || surface == NULL)
|
||||
hdc = display_win32->dummy_context_wgl.hdc;
|
||||
else
|
||||
hdc = GDK_WIN32_SURFACE (surface)->hdc;
|
||||
|
||||
if (!wglMakeCurrent (hdc, context_wgl->wgl_context))
|
||||
return FALSE;
|
||||
|
||||
if (!surfaceless && display_win32->hasWglEXTSwapControl)
|
||||
{
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
/* If there is compositing there is no particular need to delay
|
||||
* the swap when drawing on the offscreen, rendering to the screen
|
||||
* happens later anyway, and its up to the compositor to sync that
|
||||
* to the vblank. */
|
||||
do_frame_sync = ! gdk_display_is_composited (display);
|
||||
|
||||
if (do_frame_sync != context_wgl->do_frame_sync)
|
||||
{
|
||||
context_wgl->do_frame_sync = do_frame_sync;
|
||||
|
||||
wglSwapIntervalEXT (do_frame_sync ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
|
||||
{
|
||||
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
context_class->realize = gdk_win32_gl_context_wgl_realize;
|
||||
context_class->make_current = gdk_win32_gl_context_wgl_make_current;
|
||||
context_class->clear_current = gdk_win32_gl_context_wgl_clear_current;
|
||||
|
||||
draw_context_class->begin_frame = gdk_win32_gl_context_wgl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_win32_gl_context_wgl_end_frame;
|
||||
gobject_class->dispose = gdk_win32_gl_context_wgl_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_wgl_init (GdkWin32GLContextWGL *wgl_context)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_win32_display_get_wgl_version:
|
||||
* @display: a `GdkDisplay`
|
||||
* @major: (out): return location for the WGL major version
|
||||
* @minor: (out): return location for the WGL minor version
|
||||
*
|
||||
* Retrieves the version of the WGL implementation.
|
||||
*
|
||||
* Returns: %TRUE if WGL is available
|
||||
*/
|
||||
gboolean
|
||||
gdk_win32_display_get_wgl_version (GdkDisplay *display,
|
||||
int *major,
|
||||
int *minor)
|
||||
{
|
||||
GdkWin32Display *display_win32;
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
if (!GDK_IS_WIN32_DISPLAY (display))
|
||||
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;
|
||||
if (minor != NULL)
|
||||
*minor = display_win32->gl_version % 10;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,13 +35,24 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_WIN32_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
|
||||
#define GDK_WIN32_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WIN32_GL_CONTEXT, GdkWin32GLContextClass))
|
||||
#define GDK_WIN32_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WIN32_GL_CONTEXT))
|
||||
|
||||
struct _GdkWin32GLContext
|
||||
{
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
/* WGL Context Items */
|
||||
HGLRC hglrc;
|
||||
HDC gl_hdc;
|
||||
guint need_alpha_bits : 1;
|
||||
|
||||
/* other items */
|
||||
guint is_attached : 1;
|
||||
guint do_frame_sync : 1;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
/* EGL (Angle) Context Items */
|
||||
EGLContext egl_context;
|
||||
EGLConfig egl_config;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _GdkWin32GLContextClass
|
||||
@@ -49,33 +60,15 @@ struct _GdkWin32GLContextClass
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
|
||||
/* WGL */
|
||||
#define GDK_TYPE_WIN32_GL_CONTEXT_WGL (gdk_win32_gl_context_wgl_get_type())
|
||||
#define GDK_WIN32_GL_CONTEXT_WGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL, GdkWin32GLContextWGL))
|
||||
#define GDK_IS_WIN32_GL_CONTEXT_WGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL))
|
||||
|
||||
typedef struct _GdkWin32GLContextWGL GdkWin32GLContextWGL;
|
||||
|
||||
gboolean gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
GError **error);
|
||||
void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
|
||||
GdkWin32Surface *win32_surface);
|
||||
|
||||
GType gdk_win32_gl_context_wgl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* EGL */
|
||||
#define GDK_TYPE_WIN32_GL_CONTEXT_EGL (gdk_win32_gl_context_egl_get_type())
|
||||
#define GDK_WIN32_GL_CONTEXT_EGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WIN32_GL_CONTEXT_EGL, GdkWin32GLContextEGL))
|
||||
#define GDK_IS_WIN32_GL_CONTEXT_EGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WIN32_GL_CONTEXT_EGL))
|
||||
|
||||
typedef struct _GdkWin32GLContextEGL GdkWin32GLContextEGL;
|
||||
|
||||
gboolean gdk_win32_display_init_egl (GdkDisplay *display,
|
||||
GError **error);
|
||||
void gdk_win32_surface_destroy_egl_surface (GdkWin32Surface *self);
|
||||
|
||||
GType gdk_win32_gl_context_egl_get_type (void) G_GNUC_CONST;
|
||||
GdkGLContext *
|
||||
_gdk_win32_surface_create_gl_context (GdkSurface *window,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
void
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface);
|
||||
|
||||
|
||||
@@ -694,7 +694,6 @@ update_keymap (GdkKeymap *gdk_keymap)
|
||||
if (hkls_len != keymap->layout_handles->len)
|
||||
keymap->keysym_tab = g_renew (guint, keymap->keysym_tab, keysym_tab_size);
|
||||
|
||||
memset (key_state, 0, sizeof(key_state));
|
||||
memset (keymap->keysym_tab, 0, keysym_tab_size);
|
||||
g_array_set_size (keymap->layout_handles, hkls_len);
|
||||
g_array_set_size (keymap->options, hkls_len);
|
||||
|
||||
@@ -681,7 +681,7 @@ enum_monitor (HMONITOR hmonitor,
|
||||
else
|
||||
{
|
||||
/* First acquire the scale using the current screen */
|
||||
scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, NULL);
|
||||
scale = _gdk_win32_display_get_monitor_scale_factor (data->display, NULL, NULL, NULL);
|
||||
|
||||
/* acquire the scale using the monitor which the window is nearest on Windows 8.1+ */
|
||||
if (data->display->have_at_least_win81)
|
||||
@@ -695,7 +695,7 @@ enum_monitor (HMONITOR hmonitor,
|
||||
pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2;
|
||||
pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2;
|
||||
hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
|
||||
scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, hmonitor);
|
||||
scale = _gdk_win32_display_get_monitor_scale_factor (data->display, hmonitor, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,8 @@ init_root_window (GdkWin32Screen *screen_win32)
|
||||
win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||
|
||||
if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
|
||||
screen_win32->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||
screen_win32->surface_scale = _gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
else
|
||||
|
||||
@@ -352,14 +352,12 @@ RegisterGdkClass (GdkSurfaceType wtype)
|
||||
{
|
||||
char sLoc [MAX_PATH+1];
|
||||
|
||||
// try to load first icon of executable program
|
||||
if (0 != GetModuleFileName (NULL, sLoc, MAX_PATH))
|
||||
if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
|
||||
{
|
||||
ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
|
||||
|
||||
if (0 == hAppIcon && 0 == hAppIconSm)
|
||||
{
|
||||
// fallback : load icon from GTK DLL
|
||||
if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
|
||||
{
|
||||
ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
|
||||
@@ -397,13 +395,12 @@ RegisterGdkClass (GdkSurfaceType wtype)
|
||||
wcl.hbrBackground = NULL; \
|
||||
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||
|
||||
/* MSDN: CS_OWNDC is needed for OpenGL contexts */
|
||||
wcl.style |= CS_OWNDC;
|
||||
|
||||
switch (wtype)
|
||||
{
|
||||
case GDK_SURFACE_TOPLEVEL:
|
||||
case GDK_SURFACE_POPUP:
|
||||
/* MSDN: CS_OWNDC is needed for OpenGL contexts */
|
||||
wcl.style |= CS_OWNDC;
|
||||
if (0 == klassTOPLEVEL)
|
||||
{
|
||||
wcl.lpszClassName = L"gdkSurfaceToplevel";
|
||||
@@ -522,7 +519,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL, NULL);
|
||||
|
||||
dwExStyle = 0;
|
||||
owner = NULL;
|
||||
@@ -655,7 +652,6 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
impl);
|
||||
|
||||
g_object_unref (frame_clock);
|
||||
impl->hdc = GetDC (impl->handle);
|
||||
|
||||
return surface;
|
||||
}
|
||||
@@ -1231,7 +1227,6 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
&shadow_right,
|
||||
&shadow_top,
|
||||
&shadow_bottom);
|
||||
|
||||
gdk_win32_surface_set_shadow_width (surface,
|
||||
shadow_left,
|
||||
shadow_right,
|
||||
@@ -1241,10 +1236,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
gdk_surface_layout_popup_helper (surface,
|
||||
width,
|
||||
height,
|
||||
shadow_left,
|
||||
shadow_right,
|
||||
shadow_top,
|
||||
shadow_bottom,
|
||||
impl->shadow.left,
|
||||
impl->shadow.right,
|
||||
impl->shadow.top,
|
||||
impl->shadow.bottom,
|
||||
monitor,
|
||||
&bounds,
|
||||
layout,
|
||||
@@ -1264,7 +1259,9 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
final_rect.height);
|
||||
}
|
||||
else
|
||||
gdk_win32_surface_move (surface, x, y);
|
||||
{
|
||||
gdk_win32_surface_move (surface, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4418,9 +4415,9 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
|
||||
if (impl->zero_shadow)
|
||||
return;
|
||||
|
||||
impl->shadow.left = left * impl->surface_scale;;
|
||||
impl->shadow.left = left;
|
||||
impl->shadow.right = right * impl->surface_scale;
|
||||
impl->shadow.top = top * impl->surface_scale;;
|
||||
impl->shadow.top = top;
|
||||
impl->shadow.bottom = bottom * impl->surface_scale;
|
||||
impl->shadow_x = left + right;
|
||||
impl->shadow_y = top + bottom;
|
||||
@@ -4428,19 +4425,19 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
|
||||
|
||||
|
||||
int
|
||||
_gdk_win32_surface_get_scale_factor (GdkSurface *surface)
|
||||
_gdk_win32_surface_get_scale_factor (GdkSurface *window)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkWin32Surface *impl;
|
||||
GdkWin32Display *win32_display;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return 1;
|
||||
|
||||
g_return_val_if_fail (surface != NULL, 1);
|
||||
g_return_val_if_fail (window != NULL, 1);
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
display = gdk_surface_get_display (window);
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
@@ -4449,8 +4446,9 @@ _gdk_win32_surface_get_scale_factor (GdkSurface *surface)
|
||||
if (win32_display->has_fixed_scale)
|
||||
impl->surface_scale = win32_display->surface_scale;
|
||||
else
|
||||
impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||
surface,
|
||||
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||
NULL,
|
||||
GDK_SURFACE_HWND (window),
|
||||
NULL);
|
||||
|
||||
return impl->surface_scale;
|
||||
@@ -4555,7 +4553,7 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
|
||||
int scale = impl->surface_scale;
|
||||
RECT rect;
|
||||
|
||||
if (impl->drag_move_resize_context.native_move_resize_pending)
|
||||
if (GDK_IS_TOPLEVEL (surface) && impl->drag_move_resize_context.native_move_resize_pending)
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
@@ -4566,18 +4564,8 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
|
||||
|
||||
impl->next_layout.configured_width = (rect.right - rect.left + scale - 1) / scale;
|
||||
impl->next_layout.configured_height = (rect.bottom - rect.top + scale - 1) / scale;
|
||||
|
||||
if (GDK_IS_TOPLEVEL (surface))
|
||||
{
|
||||
surface->x = rect.left / scale;
|
||||
surface->y = rect.top / scale;
|
||||
}
|
||||
else if (GDK_IS_POPUP (surface))
|
||||
{
|
||||
gdk_win32_surface_get_geometry (surface,
|
||||
&surface->x, &surface->y,
|
||||
NULL, NULL);
|
||||
}
|
||||
surface->x = rect.left / scale;
|
||||
surface->y = rect.top / scale;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4624,6 +4612,7 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
||||
|
||||
impl_class->destroy_notify = gdk_win32_surface_destroy_notify;
|
||||
impl_class->drag_begin = _gdk_win32_surface_drag_begin;
|
||||
impl_class->create_gl_context = _gdk_win32_surface_create_gl_context;
|
||||
impl_class->get_scale_factor = _gdk_win32_surface_get_scale_factor;
|
||||
impl_class->request_layout = _gdk_win32_surface_request_layout;
|
||||
impl_class->compute_size = _gdk_win32_surface_compute_size;
|
||||
@@ -4666,9 +4655,9 @@ gdk_win32_popup_init (GdkWin32Popup *popup)
|
||||
|
||||
static void
|
||||
gdk_win32_popup_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (object);
|
||||
|
||||
@@ -4690,9 +4679,9 @@ gdk_win32_popup_get_property (GObject *object,
|
||||
|
||||
static void
|
||||
gdk_win32_popup_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (object);
|
||||
|
||||
@@ -4727,9 +4716,9 @@ gdk_win32_popup_class_init (GdkWin32PopupClass *class)
|
||||
|
||||
static gboolean
|
||||
gdk_win32_popup_present (GdkPopup *popup,
|
||||
int width,
|
||||
int height,
|
||||
GdkPopupLayout *layout)
|
||||
int width,
|
||||
int height,
|
||||
GdkPopupLayout *layout)
|
||||
{
|
||||
return gdk_win32_surface_present_popup (GDK_SURFACE (popup), width, height, layout);
|
||||
}
|
||||
@@ -5045,9 +5034,9 @@ gdk_win32_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLSurface
|
||||
gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config,
|
||||
gboolean is_dummy)
|
||||
_gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config,
|
||||
gboolean is_dummy)
|
||||
{
|
||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
@@ -5066,10 +5055,7 @@ gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
else
|
||||
{
|
||||
if (impl->egl_surface == EGL_NO_SURFACE)
|
||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp,
|
||||
config,
|
||||
GDK_SURFACE_HWND (surface),
|
||||
NULL);
|
||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp, config, display->gl_hwnd, NULL);
|
||||
|
||||
return impl->egl_surface;
|
||||
}
|
||||
@@ -5152,20 +5138,3 @@ gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
|
||||
|
||||
return queued_window_rect;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface)
|
||||
{
|
||||
/* If we are using ANGLE, we need to force redraw of the whole Window and its child windows
|
||||
* as we need to re-acquire the EGL surfaces that we rendered to upload to Cairo explicitly,
|
||||
* using gdk_window_invalidate_rect (), when we maximize or restore or use aerosnap
|
||||
*/
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (surface->gl_paint_context != NULL && gdk_gl_context_get_use_es (surface->gl_paint_context))
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
impl->egl_force_redraw_all = TRUE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -379,9 +379,9 @@ RECT
|
||||
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLSurface gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config,
|
||||
gboolean is_dummy);
|
||||
EGLSurface _gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config,
|
||||
gboolean is_dummy);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user