Compare commits
205 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3346d68311 | |||
| cc6ecc8b62 | |||
| 05eaffb9f2 | |||
| 67b568f464 | |||
| 19b534f7de | |||
| db8b3419c2 | |||
| 0f5ba5192a | |||
| 108c423d70 | |||
| dded10a396 | |||
| 1b080826db | |||
| 910f23ea19 | |||
| f1b50baba1 | |||
| 4453597946 | |||
| 192bfa10cb | |||
| 0781429dc5 | |||
| d760332f00 | |||
| 131be5f2e8 | |||
| 57a95c540c | |||
| 09deb1d757 | |||
| 5c4aba4b9c | |||
| 6a5d555f58 | |||
| f5dc71021f | |||
| 39005461c5 | |||
| 4dc4c00267 | |||
| d76460343a | |||
| 0d8dd0c664 | |||
| ee6491f717 | |||
| 7044951dab | |||
| 98986a25f9 | |||
| ae3e586714 | |||
| 0ef12193f9 | |||
| b695ef9168 | |||
| 7fb1389648 | |||
| f88efb811b | |||
| 466d33ca69 | |||
| d44ce1987d | |||
| 527b2c5ab1 | |||
| 4d0c2997cf | |||
| 6f04ec9dae | |||
| 00cc99818d | |||
| e51fdc1c9b | |||
| 8d5ef4ab30 | |||
| 7bdda15b86 | |||
| 4c41ef8de3 | |||
| 7aec3b0fa1 | |||
| fce23c981b | |||
| 351819b570 | |||
| a10b1b7341 | |||
| 02c6226741 | |||
| 620ccdabb5 | |||
| 4b12dc6547 | |||
| bd69d7e23f | |||
| 8648486400 | |||
| 6c00117119 | |||
| 9c4c4eaaa1 | |||
| 969b3257a7 | |||
| 65c6af31e1 | |||
| 6b8bc83420 | |||
| 30aaab5c6c | |||
| 72e2a46c05 | |||
| e06e0e8555 | |||
| 9f1d6e1f44 | |||
| 15ed1a329e | |||
| 505436340b | |||
| a27434a8a7 | |||
| 2c987861a6 | |||
| c7320df0c9 | |||
| dd666e4fe4 | |||
| e4f0418003 | |||
| 430b6f8fb1 | |||
| ba3e80cbfa | |||
| 7cd4282bad | |||
| 01e9fa9adb | |||
| 581e01b2da | |||
| 5a3b4de1b7 | |||
| 74288eceaf | |||
| 37ba057128 | |||
| 6d5ba9590b | |||
| 215f792851 | |||
| 1c55b32879 | |||
| 82eb947f41 | |||
| 485dae9f25 | |||
| eb3423312f | |||
| 04c2093d5c | |||
| ccd5992a83 | |||
| ca8d9fbe0b | |||
| 62bac44a21 | |||
| 0ddd06113d | |||
| b1fbc2ef24 | |||
| c787fe7ecb | |||
| bdb49720be | |||
| 1d448a2b8a | |||
| c5df081904 | |||
| 8a2f3e1fe5 | |||
| 8dfc627e46 | |||
| 0fce30070f | |||
| 8bfe82f686 | |||
| 7d32ec51e7 | |||
| 5784f8c2f9 | |||
| 74e01ddec5 | |||
| 1347573139 | |||
| f2b41e708d | |||
| a5555943ed | |||
| 2c023cdaed | |||
| bcc7028640 | |||
| bdee75cd0f | |||
| 94eb3d7ac0 | |||
| 0ae2acfb1a | |||
| afc5f46ca9 | |||
| e544c891ca | |||
| af0c95c11a | |||
| 4d5dc18a57 | |||
| 9f6fb161e2 | |||
| 3883a98771 | |||
| 9b44965f13 | |||
| aa6a9de6ba | |||
| 8669e8a498 | |||
| ead31db096 | |||
| 69fda941c7 | |||
| 67c9e7a4a8 | |||
| 4e4f57e091 | |||
| ac64d2d910 | |||
| 49a76257cd | |||
| 77829cf3ed | |||
| 4d10ab3d35 | |||
| e609ede597 | |||
| 2ba69abe39 | |||
| a76f515569 | |||
| a663b8c313 | |||
| f66fa16bd1 | |||
| 8390363abe | |||
| 6ff85d287a | |||
| 94c2072be8 | |||
| 64b9d53472 | |||
| a5e7b92c5d | |||
| 2da9ba63e2 | |||
| 5d02a8f5db | |||
| 834d3749c6 | |||
| 1c90bb522e | |||
| b70b058b66 | |||
| b99beeb552 | |||
| c799452973 | |||
| fd48afb77d | |||
| aaa68954c3 | |||
| 433233258b | |||
| 3eed61deba | |||
| 87e2a02e0c | |||
| 264d592012 | |||
| 0ad5094119 | |||
| 67952a9142 | |||
| ca3d942b9b | |||
| 5470a1344d | |||
| 4390f8102b | |||
| 92129a2011 | |||
| 54dffa07f3 | |||
| 1cff4bb27a | |||
| 8087250476 | |||
| 485dc052ca | |||
| 45d39c2802 | |||
| 3b4b1c6878 | |||
| ff4f07d76f | |||
| fb6c8cd466 | |||
| 8464b0484f | |||
| bee58fd09d | |||
| d25557a5ef | |||
| da3ca6604b | |||
| 74cba6c3b2 | |||
| c09718b731 | |||
| eacfa2a966 | |||
| e7f228e240 | |||
| fab82a7c25 | |||
| fc9c34897a | |||
| 28cdd3f497 | |||
| a009e26e95 | |||
| ab908c23f4 | |||
| ae21f66fe5 | |||
| 2d092ea280 | |||
| 0f9d39cdfd | |||
| a64087d481 | |||
| c85f3f4942 | |||
| d7553279ff | |||
| c86631b8a9 | |||
| c1af63de9b | |||
| 2784b03b2d | |||
| 10bdf8c645 | |||
| d63d9b2319 | |||
| d5f2b69d0c | |||
| 6818eee859 | |||
| e7f1398d85 | |||
| 880c01f8cc | |||
| 337c5e5e59 | |||
| af52ea78c6 | |||
| fe633d9ef9 | |||
| e6cce283a7 | |||
| c920236c54 | |||
| 6f86b4d220 | |||
| a085e174c5 | |||
| d3c08789a3 | |||
| 630488210b | |||
| 873f6ccfea | |||
| af15f5d004 | |||
| f328175e2f | |||
| fc65d6393a | |||
| 271afb7eab | |||
| 76133dbea7 |
@@ -57,6 +57,7 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/report*.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report*.html"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
||||
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
|
||||
@@ -172,6 +173,7 @@ macos:
|
||||
- meson -Dx11-backend=false
|
||||
-Dbroadway-backend=true
|
||||
-Dmacos-backend=true
|
||||
-Dmedia-gstreamer=disabled
|
||||
-Dintrospection=disabled
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
|
||||
@@ -15,7 +15,7 @@ meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
-Dvulkan=enabled \
|
||||
-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 _build || goto :error
|
||||
meson -Dmedia-gstreamer=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
goto :EOF
|
||||
|
||||
@@ -1,3 +1,110 @@
|
||||
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
|
||||
============================
|
||||
|
||||
|
||||
@@ -124,9 +124,6 @@
|
||||
/* 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
|
||||
|
||||
|
||||
+15
-1
@@ -21,8 +21,10 @@ 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");
|
||||
@@ -31,11 +33,23 @@ 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_window_set_child (GTK_WINDOW (window), sw);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), 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,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.Demo4.desktop</id>
|
||||
<id>org.gtk.Demo4</id>
|
||||
<launchable type="desktop-id">org.gtk.Demo4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Demo</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<description>
|
||||
@@ -30,6 +31,7 @@
|
||||
<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,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.IconBrowser4.desktop</id>
|
||||
<id>org.gtk.IconBrowser4</id>
|
||||
<launchable type="desktop-id">org.gtk.IconBrowser4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Icon Browser</name>
|
||||
<summary>Program to browse themed icons</summary>
|
||||
<description>
|
||||
@@ -29,6 +30,7 @@
|
||||
<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,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.PrintEditor4.desktop</id>
|
||||
<id>org.gtk.PrintEditor4</id>
|
||||
<launchable type="desktop-id">org.gtk.PrintEditor4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Print Editor</name>
|
||||
<summary>Program to demonstrate GTK printing</summary>
|
||||
<description>
|
||||
@@ -24,6 +25,7 @@
|
||||
<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>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.WidgetFactory4.desktop</id>
|
||||
<id>org.gtk.WidgetFactory4</id>
|
||||
<launchable type="desktop-id">org.gtk.WidgetFactory4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Widget Factory</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<description>
|
||||
@@ -31,6 +32,7 @@
|
||||
<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>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 MiB |
@@ -696,6 +696,37 @@ on_range_to_changed (GtkSpinButton *to)
|
||||
gtk_spin_button_set_value (from, v2);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
on_picture_drag_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
|
||||
picture = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, gtk_picture_get_paintable (GTK_PICTURE (picture)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_picture_drop (GtkDropTarget *dest,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
picture = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
paintable = g_value_get_object (value);
|
||||
|
||||
gtk_picture_set_paintable (GTK_PICTURE (picture), paintable);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
info_bar_response (GtkWidget *infobar, int response_id)
|
||||
{
|
||||
@@ -1182,7 +1213,7 @@ populate_flowbox (GtkWidget *flowbox)
|
||||
GtkWidget *child;
|
||||
int i;
|
||||
const char *resources[] = {
|
||||
"sunset.jpg", "snowy.jpg", "portland-rose.jpg"
|
||||
"sunset.jpg", "portland-rose.jpg", "beach.jpg", "nyc.jpg"
|
||||
};
|
||||
|
||||
if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (flowbox), "populated")))
|
||||
@@ -2040,6 +2071,8 @@ activate (GApplication *app)
|
||||
"on_page_combo_changed", (GCallback)on_page_combo_changed,
|
||||
"on_range_from_changed", (GCallback)on_range_from_changed,
|
||||
"on_range_to_changed", (GCallback)on_range_to_changed,
|
||||
"on_picture_drag_prepare", (GCallback)on_picture_drag_prepare,
|
||||
"on_picture_drop", (GCallback)on_picture_drop,
|
||||
"tab_close_cb", (GCallback)tab_close_cb,
|
||||
"increase_icon_size", (GCallback)increase_icon_size,
|
||||
"decrease_icon_size", (GCallback)decrease_icon_size,
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
<gresource prefix="/org/gtk/WidgetFactory4">
|
||||
<file>gtk-logo.webm</file>
|
||||
<file>sunset.jpg</file>
|
||||
<file>snowy.jpg</file>
|
||||
<file>portland-rose.jpg</file>
|
||||
<file>nyc.jpg</file>
|
||||
<file>beach.jpg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -1251,8 +1251,21 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box6">
|
||||
<property name="orientation">vertical</property>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/sunset.jpg</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture</property>
|
||||
<signal name="drop" handler="on_picture_drop" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
@@ -1265,8 +1278,21 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box7">
|
||||
<property name="orientation">vertical</property>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/nyc.jpg</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture</property>
|
||||
<signal name="drop" handler="on_picture_drop" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
@@ -1278,10 +1304,22 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="position">2</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box8">
|
||||
<property name="orientation">vertical</property>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/beach.jpg</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture</property>
|
||||
<signal name="drop" handler="on_picture_drop" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
@@ -1299,7 +1337,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box9">
|
||||
<object class="GtkBox" id="box8">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
</property>
|
||||
|
||||
@@ -14,19 +14,14 @@ instructions, binary downloads, etc, can be found
|
||||
The Win32 GDK backend can be influenced with some additional environment
|
||||
variables.
|
||||
|
||||
### GDK_WIN32_TABLET_INPUT_API
|
||||
### GDK_IGNORE_WINTAB
|
||||
|
||||
If this variable is set, it determines the API that GTK uses for tablet support.
|
||||
The possible values are:
|
||||
If this variable is set, GTK doesn't use the Wintab API for tablet support.
|
||||
|
||||
`none`
|
||||
: Disables tablet support
|
||||
### GDK_USE_WINTAB
|
||||
|
||||
`wintab`
|
||||
: Use the Wintab API
|
||||
|
||||
`winpointer`
|
||||
: Use the Windows Pointer Input Stack API. This is the default.
|
||||
If this variable is set, GTK uses the Wintab API for tablet support.
|
||||
This is the default.
|
||||
|
||||
## Windows-specific handling of cursors
|
||||
|
||||
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/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([]);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gprintf.h>
|
||||
@@ -463,7 +464,7 @@ gdk_broadway_display_flush_in_idle (GdkDisplay *display)
|
||||
if (broadway_display->idle_flush_id == 0)
|
||||
{
|
||||
broadway_display->idle_flush_id = g_idle_add (flush_idle, g_object_ref (display));
|
||||
g_source_set_name_by_id (broadway_display->idle_flush_id, "[gtk] flush_idle");
|
||||
gdk_source_set_static_name_by_id (broadway_display->idle_flush_id, "[gtk] flush_idle");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,4 +57,11 @@ guint gdk_parse_debug_var (const char *variable,
|
||||
# define g_memdup2(mem,size) g_memdup((mem),(size))
|
||||
#endif
|
||||
|
||||
void gdk_source_set_static_name_by_id (guint tag,
|
||||
const char *name);
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 69, 1)
|
||||
#define g_source_set_static_name(source, name) g_source_set_name ((source), (name))
|
||||
#endif
|
||||
|
||||
#endif /* __GDK__PRIVATE_H__ */
|
||||
|
||||
@@ -127,7 +127,9 @@ 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" },
|
||||
@@ -412,3 +414,17 @@ gdk_find_base_dir (const char *text,
|
||||
return dir;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_source_set_static_name_by_id (guint tag,
|
||||
const char *name)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
g_return_if_fail (tag > 0);
|
||||
|
||||
source = g_main_context_find_source_by_id (NULL, tag);
|
||||
if (source == NULL)
|
||||
return;
|
||||
|
||||
g_source_set_static_name (source, name);
|
||||
}
|
||||
|
||||
+76
-8
@@ -179,6 +179,76 @@ gdk_content_formats_new_for_gtype (GType type)
|
||||
return gdk_content_formats_new_take (data, 1, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_content_formats_parse:
|
||||
* @string: the string to parse
|
||||
*
|
||||
* Parses the given @string into `GdkContentFormats` and
|
||||
* returns the formats.
|
||||
*
|
||||
* Strings printed via [method@Gdk.ContentFormats.to_string]
|
||||
* can be read in again successfully using this function.
|
||||
*
|
||||
* If @string does not describe valid content formats, %NULL
|
||||
* is returned.
|
||||
*
|
||||
* Returns: (nullable): the content formats if @string is valid
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
GdkContentFormats *
|
||||
gdk_content_formats_parse (const char *string)
|
||||
{
|
||||
GdkContentFormatsBuilder *builder;
|
||||
char **split;
|
||||
gsize i;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
|
||||
split = g_strsplit_set (string, "\t\n\f\r ", -1); /* same as g_ascii_isspace() */
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
|
||||
/* first the GTypes */
|
||||
for (i = 0; split[i] != NULL; i++)
|
||||
{
|
||||
GType type;
|
||||
|
||||
if (split[i][0] == 0)
|
||||
continue;
|
||||
|
||||
type = g_type_from_name (split[i]);
|
||||
if (type != 0)
|
||||
gdk_content_formats_builder_add_gtype (builder, type);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* then the mime types */
|
||||
for (; split[i] != NULL; i++)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
if (split[i][0] == 0)
|
||||
continue;
|
||||
|
||||
mime_type = gdk_intern_mime_type (split[i]);
|
||||
if (mime_type)
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (split[i] != NULL)
|
||||
{
|
||||
g_strfreev (split);
|
||||
gdk_content_formats_builder_unref (builder);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_strfreev (split);
|
||||
return gdk_content_formats_builder_free_to_formats (builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_content_formats_ref:
|
||||
* @formats: a `GdkContentFormats`
|
||||
@@ -227,10 +297,8 @@ gdk_content_formats_unref (GdkContentFormats *formats)
|
||||
*
|
||||
* Prints the given @formats into a string for human consumption.
|
||||
*
|
||||
* This is meant for debugging and logging.
|
||||
*
|
||||
* The form of the representation may change at any time and is
|
||||
* not guaranteed to stay identical.
|
||||
* The result of this function can later be parsed with
|
||||
* [func@Gdk.ContentFormats.parse].
|
||||
*/
|
||||
void
|
||||
gdk_content_formats_print (GdkContentFormats *formats,
|
||||
@@ -241,20 +309,18 @@ gdk_content_formats_print (GdkContentFormats *formats,
|
||||
g_return_if_fail (formats != NULL);
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
g_string_append (string, "{ ");
|
||||
for (i = 0; i < formats->n_gtypes; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append (string, ", ");
|
||||
g_string_append (string, " ");
|
||||
g_string_append (string, g_type_name (formats->gtypes[i]));
|
||||
}
|
||||
for (i = 0; i < formats->n_mime_types; i++)
|
||||
{
|
||||
if (i > 0 || formats->n_gtypes > 0)
|
||||
g_string_append (string, ", ");
|
||||
g_string_append (string, " ");
|
||||
g_string_append (string, formats->mime_types[i]);
|
||||
}
|
||||
g_string_append (string, " }");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,6 +329,8 @@ gdk_content_formats_print (GdkContentFormats *formats,
|
||||
*
|
||||
* Prints the given @formats into a human-readable string.
|
||||
*
|
||||
* The resulting string can be parsed with [func@Gdk.ContentFormats.parse].
|
||||
*
|
||||
* This is a small wrapper around [method@Gdk.ContentFormats.print]
|
||||
* to help when debugging.
|
||||
*
|
||||
|
||||
@@ -40,6 +40,8 @@ GdkContentFormats * gdk_content_formats_new (const char
|
||||
guint n_mime_types);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats * gdk_content_formats_new_for_gtype (GType type);
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
GdkContentFormats * gdk_content_formats_parse (const char *string);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats * gdk_content_formats_ref (GdkContentFormats *formats);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
+6
-4
@@ -41,10 +41,12 @@ typedef enum {
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 15,
|
||||
GDK_DEBUG_GL_GLES = 1 << 16,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 17,
|
||||
GDK_DEBUG_GL_GLX = 1 << 18,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 19,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 20,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 21
|
||||
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,
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
|
||||
+183
-33
@@ -77,6 +77,23 @@ 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);
|
||||
|
||||
@@ -85,7 +102,7 @@ static GdkAppLaunchContext *gdk_display_real_get_app_launch_context (GdkDisplay
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_display_get_property (GObject *object,
|
||||
@@ -119,10 +136,14 @@ gdk_display_real_make_default (GdkDisplay *display)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_real_opened (GdkDisplay *display)
|
||||
static GdkGLContext *
|
||||
gdk_display_default_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
_gdk_display_manager_add_display (gdk_display_manager_get (), display);
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("The current backend does not support OpenGL"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkSeat *
|
||||
@@ -134,6 +155,12 @@ 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)
|
||||
{
|
||||
@@ -143,10 +170,11 @@ gdk_display_class_init (GdkDisplayClass *class)
|
||||
object_class->dispose = gdk_display_dispose;
|
||||
object_class->get_property = gdk_display_get_property;
|
||||
|
||||
class->get_app_launch_context = gdk_display_real_get_app_launch_context;
|
||||
class->opened = gdk_display_real_opened;
|
||||
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;
|
||||
|
||||
/**
|
||||
* GdkDisplay:composited: (attributes org.gtk.Property.get=gdk_display_is_composited)
|
||||
@@ -294,6 +322,8 @@ 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;
|
||||
|
||||
@@ -304,22 +334,26 @@ gdk_display_init (GdkDisplay *display)
|
||||
|
||||
g_queue_init (&display->queued_events);
|
||||
|
||||
display->debug_flags = _gdk_debug_flags;
|
||||
priv->debug_flags = _gdk_debug_flags;
|
||||
|
||||
display->composited = TRUE;
|
||||
display->rgba = TRUE;
|
||||
display->input_shapes = TRUE;
|
||||
priv->composited = TRUE;
|
||||
priv->rgba = TRUE;
|
||||
priv->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);
|
||||
}
|
||||
|
||||
@@ -998,21 +1032,25 @@ 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 display->input_shapes;
|
||||
return priv->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 (display->input_shapes == input_shapes)
|
||||
if (priv->input_shapes == input_shapes)
|
||||
return;
|
||||
|
||||
display->input_shapes = input_shapes;
|
||||
priv->input_shapes = input_shapes;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_INPUT_SHAPES]);
|
||||
}
|
||||
@@ -1157,32 +1195,136 @@ gdk_display_get_keymap (GdkDisplay *display)
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_display_make_gl_context_current:
|
||||
* @display: a `GdkDisplay`
|
||||
* @context: (optional): a `GdkGLContext`
|
||||
*
|
||||
* Makes the given @context the current GL context, or unsets
|
||||
* the current GL context if @context is %NULL.
|
||||
*/
|
||||
gboolean
|
||||
gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
static void
|
||||
gdk_display_init_gl (GdkDisplay *self)
|
||||
{
|
||||
return GDK_DISPLAY_GET_CLASS (display)->make_gl_context_current (display, context);
|
||||
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`
|
||||
*
|
||||
* 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`
|
||||
*/
|
||||
GdkGLContext *
|
||||
gdk_display_get_gl_context (GdkDisplay *self)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
return priv->gl_context;
|
||||
}
|
||||
|
||||
GdkDebugFlags
|
||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||
{
|
||||
return display ? display->debug_flags : _gdk_debug_flags;
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
return display ? priv->debug_flags : _gdk_debug_flags;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
GdkDebugFlags flags)
|
||||
{
|
||||
display->debug_flags = flags;
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
priv->debug_flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1207,21 +1349,25 @@ 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 display->composited;
|
||||
return priv->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 (display->composited == composited)
|
||||
if (priv->composited == composited)
|
||||
return;
|
||||
|
||||
display->composited = composited;
|
||||
priv->composited = composited;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_COMPOSITED]);
|
||||
}
|
||||
@@ -1248,21 +1394,25 @@ 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 display->rgba;
|
||||
return priv->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 (display->rgba == rgba)
|
||||
if (priv->rgba == rgba)
|
||||
return;
|
||||
|
||||
display->rgba = rgba;
|
||||
priv->rgba = rgba;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_RGBA]);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,10 @@ 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);
|
||||
|
||||
|
||||
@@ -102,11 +102,6 @@ struct _GdkDisplay
|
||||
|
||||
guint vulkan_refcount;
|
||||
#endif /* GDK_RENDERING_VULKAN */
|
||||
guint rgba : 1;
|
||||
guint composited : 1;
|
||||
guint input_shapes : 1;
|
||||
|
||||
GdkDebugFlags debug_flags;
|
||||
|
||||
GList *seats;
|
||||
};
|
||||
@@ -145,8 +140,8 @@ struct _GdkDisplayClass
|
||||
|
||||
GdkKeymap * (*get_keymap) (GdkDisplay *display);
|
||||
|
||||
gboolean (*make_gl_context_current) (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
GdkGLContext * (*init_gl) (GdkDisplay *display,
|
||||
GError **error);
|
||||
|
||||
GdkSeat * (*get_default_seat) (GdkDisplay *display);
|
||||
|
||||
@@ -211,8 +206,7 @@ GdkSurface * gdk_display_create_surface (GdkDisplay *display
|
||||
int width,
|
||||
int height);
|
||||
|
||||
gboolean gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
|
||||
|
||||
void gdk_display_set_rgba (GdkDisplay *display,
|
||||
gboolean rgba);
|
||||
|
||||
+28
-4
@@ -43,6 +43,7 @@
|
||||
typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate;
|
||||
|
||||
struct _GdkDrawContextPrivate {
|
||||
GdkDisplay *display;
|
||||
GdkSurface *surface;
|
||||
|
||||
cairo_region_t *frame_region;
|
||||
@@ -77,6 +78,7 @@ 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);
|
||||
}
|
||||
@@ -92,10 +94,31 @@ 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);
|
||||
g_assert (priv->surface != NULL);
|
||||
priv->surface->draw_contexts = g_slist_prepend (priv->surface->draw_contexts, context);
|
||||
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));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -148,7 +171,8 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
||||
P_("Display"),
|
||||
P_("The GDK display used to create the context"),
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
@@ -228,7 +252,7 @@ gdk_draw_context_get_display (GdkDrawContext *context)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
|
||||
|
||||
return priv->surface ? gdk_surface_get_display (priv->surface) : NULL;
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkframeclockprivate.h"
|
||||
#include "gdk.h"
|
||||
#include "gdk-private.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
@@ -307,12 +308,15 @@ maybe_start_idle (GdkFrameClockIdle *clock_idle,
|
||||
|
||||
if (priv->flush_idle_id == 0 && RUN_FLUSH_IDLE (priv))
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
priv->flush_idle_id = g_timeout_add_full (GDK_PRIORITY_EVENTS + 1,
|
||||
min_interval,
|
||||
gdk_frame_clock_flush_idle,
|
||||
g_object_ref (clock_idle),
|
||||
(GDestroyNotify) g_object_unref);
|
||||
g_source_set_name_by_id (priv->flush_idle_id, "[gtk] gdk_frame_clock_flush_idle");
|
||||
source = g_main_context_find_source_by_id (NULL, priv->flush_idle_id);
|
||||
g_source_set_static_name (source, "[gtk] gdk_frame_clock_flush_idle");
|
||||
}
|
||||
|
||||
if (!priv->in_paint_idle &&
|
||||
@@ -324,7 +328,7 @@ maybe_start_idle (GdkFrameClockIdle *clock_idle,
|
||||
gdk_frame_clock_paint_idle,
|
||||
g_object_ref (clock_idle),
|
||||
(GDestroyNotify) g_object_unref);
|
||||
g_source_set_name_by_id (priv->paint_idle_id, "[gtk] gdk_frame_clock_paint_idle");
|
||||
gdk_source_set_static_name_by_id (priv->paint_idle_id, "[gtk] gdk_frame_clock_paint_idle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+129
-52
@@ -89,8 +89,6 @@
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
typedef struct {
|
||||
GdkGLContext *shared_context;
|
||||
|
||||
int major;
|
||||
int minor;
|
||||
int gl_version;
|
||||
@@ -127,7 +125,28 @@ G_DEFINE_QUARK (gdk-gl-error-quark, gdk_gl_error)
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, GDK_TYPE_DRAW_CONTEXT)
|
||||
|
||||
static GPrivate thread_current_context = G_PRIVATE_INIT (g_object_unref);
|
||||
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 void
|
||||
gdk_gl_context_clear_old_updated_area (GdkGLContext *context)
|
||||
@@ -144,17 +163,14 @@ static void
|
||||
gdk_gl_context_dispose (GObject *gobject)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current;
|
||||
|
||||
gdk_gl_context_clear_old_updated_area (context);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current == context)
|
||||
if (unmask_context (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);
|
||||
}
|
||||
|
||||
@@ -174,17 +190,10 @@ 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:
|
||||
{
|
||||
GdkGLContext *context = g_value_get_object (value);
|
||||
|
||||
if (context != NULL)
|
||||
priv->shared_context = g_object_ref (context);
|
||||
}
|
||||
g_assert (g_value_get_object (value) == NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -198,12 +207,10 @@ 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, priv->shared_context);
|
||||
g_value_set_object (value, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -333,23 +340,27 @@ 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])
|
||||
@@ -379,15 +390,6 @@ 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
|
||||
@@ -406,6 +408,7 @@ 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;
|
||||
@@ -414,7 +417,13 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
/**
|
||||
* GdkGLContext:shared-context: (attributes org.gtk.Property.get=gdk_gl_context_get_shared_context)
|
||||
*
|
||||
* The `GdkGLContext` that this context is sharing data with, or %NULL
|
||||
* 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.
|
||||
*/
|
||||
obj_pspecs[PROP_SHARED_CONTEXT] =
|
||||
g_param_spec_object ("shared-context",
|
||||
@@ -423,7 +432,8 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
GDK_TYPE_GL_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_DEPRECATED);
|
||||
|
||||
gobject_class->set_property = gdk_gl_context_set_property;
|
||||
gobject_class->get_property = gdk_gl_context_get_property;
|
||||
@@ -441,6 +451,21 @@ 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)
|
||||
{
|
||||
@@ -812,6 +837,44 @@ 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.
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
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`
|
||||
@@ -1092,12 +1155,16 @@ void
|
||||
gdk_gl_context_make_current (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current, *masked_context;
|
||||
gboolean surfaceless;
|
||||
|
||||
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 == context)
|
||||
if (current == masked_context)
|
||||
return;
|
||||
|
||||
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
||||
@@ -1114,11 +1181,15 @@ gdk_gl_context_make_current (GdkGLContext *context)
|
||||
}
|
||||
}
|
||||
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), context))
|
||||
if (!GDK_GL_CONTEXT_GET_CLASS (context)->make_current (context, surfaceless))
|
||||
{
|
||||
g_private_replace (&thread_current_context, g_object_ref (context));
|
||||
gdk_gl_context_check_extensions (context);
|
||||
g_warning ("gdk_gl_context_make_current() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_ref (context);
|
||||
g_private_replace (&thread_current_context, masked_context);
|
||||
gdk_gl_context_check_extensions (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1157,18 +1228,22 @@ gdk_gl_context_get_surface (GdkGLContext *context)
|
||||
* gdk_gl_context_get_shared_context: (attributes org.gtk.Method.get_property=shared-context)
|
||||
* @context: a `GdkGLContext`
|
||||
*
|
||||
* Retrieves the `GdkGLContext` that this @context share data with.
|
||||
* Used to retrieves the `GdkGLContext` that this @context share data with.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a `GdkGLContext`
|
||||
* 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.
|
||||
*/
|
||||
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 priv->shared_context;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1208,12 +1283,14 @@ gdk_gl_context_get_version (GdkGLContext *context,
|
||||
void
|
||||
gdk_gl_context_clear_current (void)
|
||||
{
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current != NULL)
|
||||
{
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (current)), NULL))
|
||||
GdkGLContext *context = unmask_context (current);
|
||||
|
||||
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
}
|
||||
}
|
||||
@@ -1228,11 +1305,11 @@ gdk_gl_context_clear_current (void)
|
||||
GdkGLContext *
|
||||
gdk_gl_context_get_current (void)
|
||||
{
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
|
||||
return current;
|
||||
return unmask_context (current);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
+5
-2
@@ -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_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_gl_context_get_surface (GdkGLContext *context);
|
||||
GDK_DEPRECATED_IN_4_4_FOR(gdk_gl_context_is_shared)
|
||||
GdkGLContext * gdk_gl_context_get_shared_context (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_gl_context_get_version (GdkGLContext *context,
|
||||
@@ -54,6 +54,9 @@ 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,6 +27,13 @@
|
||||
|
||||
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))
|
||||
@@ -45,10 +52,16 @@ struct _GdkGLContextClass
|
||||
{
|
||||
GdkDrawContextClass parent_class;
|
||||
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
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);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -73,6 +86,8 @@ 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);
|
||||
|
||||
|
||||
+10
-80
@@ -1065,87 +1065,23 @@ gdk_surface_get_mapped (GdkSurface *surface)
|
||||
return GDK_SURFACE_IS_MAPPED (surface);
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_surface_get_shared_data_gl_context (GdkSurface *surface)
|
||||
{
|
||||
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 **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 (!gdk_display_prepare_gl (surface->display, error))
|
||||
return NULL;
|
||||
|
||||
if (surface->gl_paint_context == 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);
|
||||
surface->gl_paint_context = gdk_surface_create_gl_context (surface, error);
|
||||
if (surface->gl_paint_context == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (internal_error != NULL)
|
||||
if (!gdk_gl_context_realize (surface->gl_paint_context, error))
|
||||
{
|
||||
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));
|
||||
g_clear_object (&surface->gl_paint_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1170,19 +1106,13 @@ 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);
|
||||
|
||||
paint_context = gdk_surface_get_paint_gl_context (surface, error);
|
||||
if (paint_context == NULL)
|
||||
if (!gdk_display_prepare_gl (surface->display, error))
|
||||
return NULL;
|
||||
|
||||
return GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface,
|
||||
FALSE,
|
||||
paint_context,
|
||||
error);
|
||||
return gdk_gl_context_new_for_surface (surface);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -160,10 +160,6 @@ 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);
|
||||
};
|
||||
@@ -266,7 +262,6 @@ 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,
|
||||
|
||||
@@ -197,7 +197,7 @@ gdk_display_link_source_new (void)
|
||||
gdk_display_link_source_frame_cb,
|
||||
source);
|
||||
|
||||
g_source_set_name (source, "[gdk] quartz frame clock");
|
||||
g_source_set_static_name (source, "[gdk] quartz frame clock");
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -637,17 +637,13 @@ gdk_macos_display_load_clipboard (GdkMacosDisplay *self)
|
||||
GDK_DISPLAY (self)->clipboard = _gdk_macos_clipboard_new (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *gl_context)
|
||||
static GdkGLContext *
|
||||
gdk_macos_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
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));
|
||||
return g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -695,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->make_gl_context_current = gdk_macos_display_make_gl_context_current;
|
||||
display_class->init_gl = gdk_macos_display_init_gl;
|
||||
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;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include "gdkmacosdevice-private.h"
|
||||
#include "gdkmacoscursor-private.h"
|
||||
@@ -161,7 +162,7 @@ gdk_macos_drag_drop_done (GdkDrag *drag,
|
||||
gdk_macos_zoomback_timeout,
|
||||
zb,
|
||||
(GDestroyNotify) gdk_macos_zoomback_destroy);
|
||||
g_source_set_name_by_id (id, "[gtk] gdk_macos_zoomback_timeout");
|
||||
gdk_source_set_static_name_by_id (id, "[gtk] gdk_macos_zoomback_timeout");
|
||||
g_object_unref (drag);
|
||||
}
|
||||
|
||||
@@ -242,9 +243,11 @@ gdk_macos_drag_drop_performed (GdkDrag *drag,
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
g_object_ref (self);
|
||||
drag_ungrab (self);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1063,7 +1063,7 @@ _gdk_macos_event_source_new (GdkMacosDisplay *display)
|
||||
event_poll_fd.fd = -1;
|
||||
|
||||
source = g_source_new (&event_funcs, sizeof (GdkMacosEventSource));
|
||||
g_source_set_name (source, "GDK Quartz event source");
|
||||
g_source_set_static_name (source, "GDK Quartz event source");
|
||||
g_source_add_poll (source, &event_poll_fd);
|
||||
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
|
||||
g_source_set_can_recurse (source, TRUE);
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
#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 "gdkmacosglcontext.h"
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
@@ -55,11 +57,6 @@ 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
|
||||
|
||||
|
||||
@@ -170,12 +170,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,21 +192,16 @@ 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));
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
shared_data = gdk_surface_get_shared_data_gl_context (surface);
|
||||
display = gdk_gl_context_get_display (context);
|
||||
shared = gdk_display_get_gl_context (display);
|
||||
|
||||
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 (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
|
||||
GDK_DISPLAY_NOTE (display,
|
||||
OPENGL,
|
||||
g_message ("Creating NSOpenGLContext (version %d.%d)",
|
||||
major, minor));
|
||||
@@ -253,7 +248,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
|
||||
GLint renderer_id = 0;
|
||||
[gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
|
||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
|
||||
GDK_DISPLAY_NOTE (display,
|
||||
OPENGL,
|
||||
g_message ("Created NSOpenGLContext[%p] using %s",
|
||||
gl_context,
|
||||
@@ -315,9 +310,7 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
* want to replace our damage region for the next frame (to avoid
|
||||
* doing it multiple times).
|
||||
*/
|
||||
if (!self->is_attached &&
|
||||
gdk_gl_context_get_shared_context (GDK_GL_CONTEXT (context)))
|
||||
ensure_gl_view (self);
|
||||
ensure_gl_view (self);
|
||||
|
||||
if (self->needs_resize)
|
||||
{
|
||||
@@ -410,6 +403,57 @@ 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)
|
||||
{
|
||||
@@ -478,52 +522,4 @@ 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
|
||||
|
||||
@@ -358,20 +358,6 @@ 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)
|
||||
@@ -495,7 +481,6 @@ 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;
|
||||
|
||||
@@ -460,6 +460,7 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
|
||||
pointer->cursor_timeout_id == 0)
|
||||
{
|
||||
guint id;
|
||||
GSource *source;
|
||||
|
||||
gdk_wayland_pointer_stop_cursor_animation (pointer);
|
||||
|
||||
@@ -467,7 +468,8 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
|
||||
id = g_timeout_add (next_image_delay,
|
||||
(GSourceFunc) gdk_wayland_device_update_surface_cursor,
|
||||
device);
|
||||
g_source_set_name_by_id (id, "[gtk] gdk_wayland_device_update_surface_cursor");
|
||||
source = g_main_context_find_source_by_id (NULL, id);
|
||||
g_source_set_static_name (source, "[gtk] gdk_wayland_device_update_surface_cursor");
|
||||
pointer->cursor_timeout_id = id;
|
||||
}
|
||||
else
|
||||
@@ -2218,7 +2220,7 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
timeout = (seat->repeat_deadline - now) / 1000L;
|
||||
|
||||
seat->repeat_timer = g_timeout_add (timeout, keyboard_repeat, seat);
|
||||
g_source_set_name_by_id (seat->repeat_timer, "[gtk] keyboard_repeat");
|
||||
gdk_source_set_static_name_by_id (seat->repeat_timer, "[gtk] keyboard_repeat");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3093,6 +3095,11 @@ 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);
|
||||
|
||||
@@ -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->make_gl_context_current = gdk_wayland_display_make_gl_context_current;
|
||||
display_class->init_gl = gdk_wayland_display_init_gl;
|
||||
|
||||
display_class->get_monitors = gdk_wayland_display_get_monitors;
|
||||
display_class->get_monitor_at_surface = gdk_wayland_display_get_monitor_at_surface;
|
||||
|
||||
@@ -153,14 +153,12 @@ 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
|
||||
|
||||
@@ -290,8 +290,10 @@ data_source_dnd_finished (void *data,
|
||||
{
|
||||
GdkDrag *drag = data;
|
||||
|
||||
g_object_ref (drag);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
g_object_unref (drag);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+166
-162
@@ -22,7 +22,9 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkglcontext-wayland.h"
|
||||
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdksurface-wayland.h"
|
||||
|
||||
#include "gdkwaylanddisplay.h"
|
||||
#include "gdkwaylandglcontext.h"
|
||||
@@ -53,14 +55,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_gl_context_get_shared_context (context);
|
||||
GdkGLContext *shared_data_context = gdk_surface_get_shared_data_gl_context (gdk_gl_context_get_surface (context));
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
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);
|
||||
@@ -120,10 +122,9 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
||||
use_es ? "yes" : "no"));
|
||||
|
||||
ctx = eglCreateContext (display_wayland->egl_display,
|
||||
context_wayland->egl_config,
|
||||
display_wayland->egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
|
||||
/* If context creation failed without the ES bit, let's try again with it */
|
||||
@@ -147,10 +148,9 @@ 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,
|
||||
context_wayland->egl_config,
|
||||
display_wayland->egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
}
|
||||
|
||||
@@ -177,10 +177,9 @@ 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,
|
||||
context_wayland->egl_config,
|
||||
display_wayland->egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
}
|
||||
|
||||
@@ -199,6 +198,8 @@ 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;
|
||||
}
|
||||
|
||||
@@ -213,17 +214,8 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context)
|
||||
|
||||
if (display_wayland->have_egl_buffer_age)
|
||||
{
|
||||
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);
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface);
|
||||
gdk_gl_context_make_current (context);
|
||||
eglQuerySurface (display_wayland->egl_display, egl_surface,
|
||||
EGL_BUFFER_AGE_EXT, &buffer_age);
|
||||
|
||||
@@ -256,6 +248,47 @@ 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)
|
||||
@@ -264,18 +297,13 @@ 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,
|
||||
context_wayland->egl_config);
|
||||
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface);
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
@@ -322,9 +350,12 @@ 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;
|
||||
}
|
||||
|
||||
@@ -340,6 +371,8 @@ 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)
|
||||
@@ -348,7 +381,7 @@ gdk_wayland_display_get_egl_display (GdkDisplay *display)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), NULL);
|
||||
|
||||
if (!gdk_wayland_display_init_gl (display))
|
||||
if (!gdk_display_prepare_gl (display, NULL))
|
||||
return NULL;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
@@ -393,71 +426,11 @@ 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 gboolean
|
||||
find_eglconfig_for_surface (GdkSurface *surface,
|
||||
EGLConfig *egl_config_out,
|
||||
GError **error)
|
||||
static EGLConfig
|
||||
get_eglconfig (EGLDisplay dpy)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig config;
|
||||
@@ -482,59 +455,129 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
/* Pick first valid configuration i guess? */
|
||||
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;
|
||||
}
|
||||
if (!eglChooseConfig (dpy, attrs, &config, 1, &count) || count < 1)
|
||||
return NULL;
|
||||
|
||||
g_assert (egl_config_out);
|
||||
*egl_config_out = config;
|
||||
|
||||
return TRUE;
|
||||
return config;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
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);
|
||||
GdkWaylandGLContext *context;
|
||||
EGLConfig config;
|
||||
#undef MAX_EGL_ATTRS
|
||||
|
||||
if (!gdk_wayland_display_init_gl (display))
|
||||
GdkGLContext *
|
||||
gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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 (!display_wayland->have_egl_khr_create_context)
|
||||
if (!epoxy_has_egl_extension (dpy, "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 (!find_eglconfig_for_surface (surface, &config, error))
|
||||
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;
|
||||
}
|
||||
|
||||
context = g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
|
||||
"surface", surface,
|
||||
"shared-context", share,
|
||||
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->egl_config = config;
|
||||
context->is_attached = attached;
|
||||
display_wayland->egl_display = dpy;
|
||||
display_wayland->egl_major_version = major;
|
||||
display_wayland->egl_minor_version = minor;
|
||||
|
||||
return GDK_GL_CONTEXT (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");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -563,42 +606,3 @@ 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,8 +36,6 @@ struct _GdkWaylandGLContext
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
EGLContext egl_context;
|
||||
EGLConfig egl_config;
|
||||
gboolean is_attached;
|
||||
};
|
||||
|
||||
struct _GdkWaylandGLContextClass
|
||||
@@ -45,13 +43,8 @@ struct _GdkWaylandGLContextClass
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gdk_wayland_display_init_gl (GdkDisplay *display);
|
||||
GdkGLContext * gdk_wayland_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attach,
|
||||
GdkGLContext *share,
|
||||
GdkGLContext * gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||
GError **error);
|
||||
gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -182,11 +182,6 @@ 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,7 +103,6 @@ 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;
|
||||
@@ -111,7 +110,6 @@ struct _GdkWaylandSurface
|
||||
struct wl_event_queue *event_queue;
|
||||
|
||||
EGLSurface egl_surface;
|
||||
EGLSurface dummy_egl_surface;
|
||||
|
||||
uint32_t reposition_token;
|
||||
uint32_t received_reposition_token;
|
||||
@@ -2901,18 +2899,6 @@ 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);
|
||||
@@ -4238,7 +4224,6 @@ 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;
|
||||
}
|
||||
@@ -4304,8 +4289,7 @@ gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface)
|
||||
}
|
||||
|
||||
EGLSurface
|
||||
gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config)
|
||||
gdk_wayland_surface_get_egl_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkWaylandSurface *impl;
|
||||
@@ -4320,35 +4304,12 @@ 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, config, egl_window, NULL);
|
||||
eglCreateWindowSurface (display->egl_display, display->egl_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,6 +22,9 @@
|
||||
|
||||
#include "gdkwaylandsurface.h"
|
||||
|
||||
#include <wayland-egl.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel,
|
||||
@@ -38,4 +41,6 @@ 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
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2020 the GTK team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdksurface.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "gdkwin32.h"
|
||||
#include "gdkdevice-winpointer.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkDeviceWinpointer, gdk_device_winpointer, GDK_TYPE_DEVICE)
|
||||
|
||||
static GdkModifierType
|
||||
get_keyboard_mask (void)
|
||||
{
|
||||
GdkModifierType mask = 0;
|
||||
BYTE kbd[256];
|
||||
|
||||
GetKeyboardState (kbd);
|
||||
if (kbd[VK_SHIFT] & 0x80)
|
||||
mask |= GDK_SHIFT_MASK;
|
||||
if (kbd[VK_CAPITAL] & 0x80)
|
||||
mask |= GDK_LOCK_MASK;
|
||||
if (kbd[VK_CONTROL] & 0x80)
|
||||
mask |= GDK_CONTROL_MASK;
|
||||
if (kbd[VK_MENU] & 0x80)
|
||||
mask |= GDK_ALT_MASK;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_winpointer_query_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface **child_window,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDeviceWinpointer *device_winpointer;
|
||||
POINT point;
|
||||
HWND hwnd, hwndc;
|
||||
int scale;
|
||||
|
||||
device_winpointer = GDK_DEVICE_WINPOINTER (device);
|
||||
if (window)
|
||||
{
|
||||
scale = GDK_WIN32_SURFACE (window)->surface_scale;
|
||||
hwnd = GDK_SURFACE_HWND (window);
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkDisplay *display = gdk_device_get_display (device);
|
||||
|
||||
scale = GDK_WIN32_DISPLAY (display)->surface_scale;
|
||||
hwnd = NULL;
|
||||
}
|
||||
|
||||
GetCursorPos (&point);
|
||||
|
||||
if (hwnd)
|
||||
ScreenToClient (hwnd, &point);
|
||||
|
||||
if (win_x)
|
||||
*win_x = point.x / scale;
|
||||
|
||||
if (win_y)
|
||||
*win_y = point.y / scale;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
if (win_x)
|
||||
*win_x += _gdk_offset_x;
|
||||
|
||||
if (win_y)
|
||||
*win_y += _gdk_offset_y;
|
||||
}
|
||||
|
||||
if (hwnd && child_window)
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_window = gdk_win32_handle_table_lookup (hwndc);
|
||||
else
|
||||
*child_window = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
*mask = get_keyboard_mask ();
|
||||
*mask |= device_winpointer->last_button_mask;
|
||||
}
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_device_winpointer_grab (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
{
|
||||
return GDK_GRAB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_ungrab (GdkDevice *device,
|
||||
guint32 time_)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_device_winpointer_surface_at_position (GdkDevice *device,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_init (GdkDeviceWinpointer *device_winpointer)
|
||||
{
|
||||
device_winpointer->device_handle = NULL;
|
||||
device_winpointer->start_cursor_id = 0;
|
||||
device_winpointer->end_cursor_id = 0;
|
||||
|
||||
device_winpointer->origin_x = 0;
|
||||
device_winpointer->origin_y = 0;
|
||||
device_winpointer->scale_x = 0.0;
|
||||
device_winpointer->scale_y = 0.0;
|
||||
|
||||
device_winpointer->last_axis_data = NULL;
|
||||
device_winpointer->num_axes = 0;
|
||||
device_winpointer->last_button_mask = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_finalize (GObject *object)
|
||||
{
|
||||
GdkDeviceWinpointer *device_winpointer = GDK_DEVICE_WINPOINTER (object);
|
||||
|
||||
g_clear_object (&device_winpointer->tool_pen);
|
||||
g_clear_object (&device_winpointer->tool_eraser);
|
||||
|
||||
g_free (device_winpointer->last_axis_data);
|
||||
|
||||
G_OBJECT_CLASS (gdk_device_winpointer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_winpointer_class_init (GdkDeviceWinpointerClass *klass)
|
||||
{
|
||||
GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_device_winpointer_finalize;
|
||||
device_class->set_surface_cursor = gdk_device_winpointer_set_surface_cursor;
|
||||
device_class->grab = gdk_device_winpointer_grab;
|
||||
device_class->ungrab = gdk_device_winpointer_ungrab;
|
||||
device_class->surface_at_position = gdk_device_winpointer_surface_at_position;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2020 the GTK team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DEVICE_WINPOINTER_H__
|
||||
#define __GDK_DEVICE_WINPOINTER_H__
|
||||
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE_WINPOINTER (gdk_device_winpointer_get_type ())
|
||||
#define GDK_DEVICE_WINPOINTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointer))
|
||||
#define GDK_DEVICE_WINPOINTER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointerClass))
|
||||
#define GDK_IS_DEVICE_WINPOINTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_WINPOINTER))
|
||||
#define GDK_IS_DEVICE_WINPOINTER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_WINPOINTER))
|
||||
#define GDK_DEVICE_WINPOINTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_WINPOINTER, GdkDeviceWinpointerClass))
|
||||
|
||||
typedef struct _GdkDeviceWinpointer GdkDeviceWinpointer;
|
||||
typedef struct _GdkDeviceWinpointerClass GdkDeviceWinpointerClass;
|
||||
|
||||
struct _GdkDeviceWinpointer
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
|
||||
HANDLE device_handle;
|
||||
UINT32 start_cursor_id;
|
||||
UINT32 end_cursor_id;
|
||||
|
||||
int origin_x;
|
||||
int origin_y;
|
||||
double scale_x;
|
||||
double scale_y;
|
||||
|
||||
double *last_axis_data;
|
||||
unsigned num_axes;
|
||||
GdkModifierType last_button_mask;
|
||||
|
||||
GdkDeviceTool *tool_pen;
|
||||
GdkDeviceTool *tool_eraser;
|
||||
};
|
||||
|
||||
struct _GdkDeviceWinpointerClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_device_winpointer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_WINPOINTER_H__ */
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "gdkdevice-win32.h"
|
||||
#include "gdkdevice-virtual.h"
|
||||
#include "gdkdevice-wintab.h"
|
||||
#include "gdkinput-winpointer.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
|
||||
@@ -372,6 +371,9 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
|
||||
|
||||
wintab_contexts = NULL;
|
||||
|
||||
if (_gdk_input_ignore_wintab)
|
||||
return;
|
||||
|
||||
n = GetSystemDirectory (&dummy, 0);
|
||||
|
||||
if (n <= 0)
|
||||
@@ -686,8 +688,6 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
GdkSeat *seat;
|
||||
GdkDisplayManager *display_manager = NULL;
|
||||
GdkDisplay *default_display = NULL;
|
||||
const char *tablet_input_api_user_preference = NULL;
|
||||
gboolean have_tablet_input_api_preference = FALSE;
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
|
||||
device_manager->core_pointer =
|
||||
@@ -728,48 +728,18 @@ gdk_device_manager_win32_constructed (GObject *object)
|
||||
gdk_seat_default_add_physical_device (GDK_SEAT_DEFAULT (seat), device_manager->system_keyboard);
|
||||
g_object_unref (seat);
|
||||
|
||||
tablet_input_api_user_preference = g_getenv ("GDK_WIN32_TABLET_INPUT_API");
|
||||
if (g_strcmp0 (tablet_input_api_user_preference, "none") == 0)
|
||||
{
|
||||
have_tablet_input_api_preference = TRUE;
|
||||
_gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_NONE;
|
||||
}
|
||||
else if (g_strcmp0 (tablet_input_api_user_preference, "wintab") == 0)
|
||||
{
|
||||
have_tablet_input_api_preference = TRUE;
|
||||
_gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINTAB;
|
||||
}
|
||||
else if (g_strcmp0 (tablet_input_api_user_preference, "winpointer") == 0)
|
||||
{
|
||||
have_tablet_input_api_preference = TRUE;
|
||||
_gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINPOINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
have_tablet_input_api_preference = FALSE;
|
||||
_gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINPOINTER;
|
||||
}
|
||||
/* Only call Wintab init stuff after the default display
|
||||
* is globally known and accessible through the display manager
|
||||
* singleton. Approach lifted from gtkmodules.c.
|
||||
*/
|
||||
display_manager = gdk_display_manager_get ();
|
||||
g_assert (display_manager != NULL);
|
||||
default_display = gdk_display_manager_get_default_display (display_manager);
|
||||
g_assert (default_display == NULL);
|
||||
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
|
||||
{
|
||||
if (!gdk_winpointer_initialize () && !have_tablet_input_api_preference)
|
||||
_gdk_win32_tablet_input_api = GDK_WIN32_TABLET_INPUT_API_WINTAB;
|
||||
}
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINTAB)
|
||||
{
|
||||
/* Only call Wintab init stuff after the default display
|
||||
* is globally known and accessible through the display manager
|
||||
* singleton. Approach lifted from gtkmodules.c.
|
||||
*/
|
||||
display_manager = gdk_display_manager_get ();
|
||||
g_assert (display_manager != NULL);
|
||||
default_display = gdk_display_manager_get_default_display (display_manager);
|
||||
g_assert (default_display == NULL);
|
||||
|
||||
g_signal_connect (display_manager, "notify::default-display",
|
||||
G_CALLBACK (wintab_default_display_notify_cb),
|
||||
NULL);
|
||||
}
|
||||
g_signal_connect (display_manager, "notify::default-display",
|
||||
G_CALLBACK (wintab_default_display_notify_cb),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -782,7 +752,7 @@ gdk_device_manager_win32_class_init (GdkDeviceManagerWin32Class *klass)
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wintab_set_tablet_active (void)
|
||||
_gdk_input_set_tablet_active (void)
|
||||
{
|
||||
GList *tmp_list;
|
||||
HCTX *hctx;
|
||||
@@ -793,7 +763,7 @@ _gdk_wintab_set_tablet_active (void)
|
||||
if (!wintab_contexts)
|
||||
return; /* No tablet devices found, or Wintab not initialized yet */
|
||||
|
||||
GDK_NOTE (INPUT, g_print ("_gdk_wintab_set_tablet_active: "
|
||||
GDK_NOTE (INPUT, g_print ("_gdk_input_set_tablet_active: "
|
||||
"Bringing Wintab contexts to the top of the overlap order\n"));
|
||||
|
||||
tmp_list = wintab_contexts;
|
||||
@@ -896,7 +866,7 @@ gdk_device_manager_find_wintab_device (GdkDeviceManagerWin32 *device_manager,
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_wintab_make_event (GdkDisplay *display,
|
||||
gdk_input_other_event (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
GdkSurface *window)
|
||||
{
|
||||
@@ -924,7 +894,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
|
||||
if (window != wintab_window)
|
||||
{
|
||||
g_warning ("gdk_wintab_make_event: not wintab_window?");
|
||||
g_warning ("gdk_input_other_event: not wintab_window?");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -935,7 +905,7 @@ gdk_wintab_make_event (GdkDisplay *display,
|
||||
g_object_ref (window);
|
||||
|
||||
GDK_NOTE (EVENTS_OR_INPUT,
|
||||
g_print ("gdk_wintab_make_event: window=%p %+g%+g\n",
|
||||
g_print ("gdk_input_other_event: window=%p %+g%+g\n",
|
||||
window ? GDK_SURFACE_HWND (window) : NULL, x, y));
|
||||
|
||||
if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
|
||||
|
||||
@@ -40,8 +40,6 @@ struct _GdkDeviceManagerWin32
|
||||
/* Fake physical devices */
|
||||
GdkDevice *system_pointer;
|
||||
GdkDevice *system_keyboard;
|
||||
|
||||
GList *winpointer_devices;
|
||||
GList *wintab_devices;
|
||||
|
||||
/* Bumped up every time a wintab device enters the proximity
|
||||
@@ -58,8 +56,8 @@ struct _GdkDeviceManagerWin32Class
|
||||
|
||||
GType gdk_device_manager_win32_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _gdk_wintab_set_tablet_active (void);
|
||||
GdkEvent * gdk_wintab_make_event (GdkDisplay *display,
|
||||
void _gdk_input_set_tablet_active (void);
|
||||
GdkEvent * gdk_input_other_event (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
GdkSurface *window);
|
||||
|
||||
|
||||
+139
-58
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
|
||||
#include "gdk.h"
|
||||
@@ -480,6 +481,7 @@ 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)
|
||||
@@ -655,6 +657,13 @@ 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;
|
||||
}
|
||||
@@ -981,31 +990,32 @@ _gdk_win32_check_on_arm64 (GdkWin32Display *display)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_display_init (GdkWin32Display *display)
|
||||
gdk_win32_display_init (GdkWin32Display *display_win32)
|
||||
{
|
||||
const char *scale_str = g_getenv ("GDK_SCALE");
|
||||
|
||||
display->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR));
|
||||
display_win32->monitors = G_LIST_MODEL (g_list_store_new (GDK_TYPE_MONITOR));
|
||||
|
||||
_gdk_win32_enable_hidpi (display);
|
||||
_gdk_win32_check_on_arm64 (display);
|
||||
_gdk_win32_enable_hidpi (display_win32);
|
||||
_gdk_win32_check_on_arm64 (display_win32);
|
||||
|
||||
/* if we have DPI awareness, set up fixed scale if set */
|
||||
if (display->dpi_aware_type != PROCESS_DPI_UNAWARE &&
|
||||
if (display_win32->dpi_aware_type != PROCESS_DPI_UNAWARE &&
|
||||
scale_str != NULL)
|
||||
{
|
||||
display->surface_scale = atol (scale_str);
|
||||
display_win32->surface_scale = atol (scale_str);
|
||||
|
||||
if (display->surface_scale <= 0)
|
||||
display->surface_scale = 1;
|
||||
if (display_win32->surface_scale <= 0)
|
||||
display_win32->surface_scale = 1;
|
||||
|
||||
display->has_fixed_scale = TRUE;
|
||||
display_win32->has_fixed_scale = TRUE;
|
||||
}
|
||||
else
|
||||
display->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display, NULL, NULL, NULL);
|
||||
display_win32->surface_scale =
|
||||
gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
|
||||
_gdk_win32_display_init_cursors (display);
|
||||
gdk_win32_display_check_composited (display);
|
||||
_gdk_win32_display_init_cursors (display_win32);
|
||||
gdk_win32_display_check_composited (display_win32);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1056,64 +1066,64 @@ gdk_win32_display_get_monitors (GdkDisplay *display)
|
||||
}
|
||||
|
||||
guint
|
||||
_gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
||||
HMONITOR hmonitor,
|
||||
HWND hwnd,
|
||||
int *dpi)
|
||||
gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
GdkSurface *surface,
|
||||
HMONITOR hmonitor)
|
||||
{
|
||||
gboolean is_scale_acquired = FALSE;
|
||||
gboolean use_dpi_for_monitor = FALSE;
|
||||
guint dpix, dpiy;
|
||||
|
||||
if (win32_display->have_at_least_win81)
|
||||
if (display_win32->have_at_least_win81)
|
||||
{
|
||||
if (hmonitor != NULL)
|
||||
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)
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
if (display_win32->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 = GetDC (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);
|
||||
|
||||
/* in case we can't get the DC for the window, return 1 for the scale */
|
||||
if (hdc == NULL)
|
||||
{
|
||||
if (dpi != NULL)
|
||||
*dpi = USER_DEFAULT_SCREEN_DPI;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
|
||||
dpix = GetDeviceCaps (hdc, LOGPIXELSX);
|
||||
dpiy = GetDeviceCaps (hdc, LOGPIXELSY);
|
||||
ReleaseDC (hwnd, hdc);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
is_scale_acquired = TRUE;
|
||||
}
|
||||
@@ -1121,21 +1131,13 @@ _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
||||
if (is_scale_acquired)
|
||||
/* USER_DEFAULT_SCREEN_DPI = 96, in winuser.h */
|
||||
{
|
||||
if (dpi != NULL)
|
||||
*dpi = dpix;
|
||||
|
||||
if (win32_display->has_fixed_scale)
|
||||
return win32_display->surface_scale;
|
||||
if (display_win32->has_fixed_scale)
|
||||
return display_win32->surface_scale;
|
||||
else
|
||||
return dpix / USER_DEFAULT_SCREEN_DPI > 1 ? dpix / USER_DEFAULT_SCREEN_DPI : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dpi != NULL)
|
||||
*dpi = USER_DEFAULT_SCREEN_DPI;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1146,6 +1148,85 @@ 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)
|
||||
{
|
||||
@@ -1171,7 +1252,6 @@ 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;
|
||||
|
||||
@@ -1182,6 +1262,7 @@ 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,6 +106,12 @@ typedef struct _GdkWin32KernelCPUFuncs
|
||||
funcIsWow64Process2 isWow64Process2;
|
||||
} GdkWin32KernelCPUFuncs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HDC hdc;
|
||||
HGLRC hglrc;
|
||||
} GdkWin32GLDummyContextWGL;
|
||||
|
||||
struct _GdkWin32Display
|
||||
{
|
||||
GdkDisplay display;
|
||||
@@ -119,15 +125,15 @@ struct _GdkWin32Display
|
||||
HWND hwnd;
|
||||
|
||||
/* WGL/OpenGL Items */
|
||||
guint have_wgl : 1;
|
||||
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
||||
int wgl_pixel_format;
|
||||
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
|
||||
|
||||
@@ -185,10 +191,9 @@ GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
|
||||
|
||||
void gdk_win32_display_check_composited (GdkWin32Display *display);
|
||||
|
||||
guint _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
||||
HMONITOR hmonitor,
|
||||
HWND hwnd,
|
||||
int *dpi);
|
||||
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||
GdkSurface *surface,
|
||||
HMONITOR hmonitor);
|
||||
|
||||
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
@@ -793,7 +795,7 @@ gdk_drag_new (GdkDisplay *display,
|
||||
GdkDragProtocol protocol)
|
||||
{
|
||||
GdkWin32Drag *drag_win32;
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkDrag *drag;
|
||||
|
||||
drag_win32 = g_object_new (GDK_TYPE_WIN32_DRAG,
|
||||
@@ -805,10 +807,10 @@ gdk_drag_new (GdkDisplay *display,
|
||||
|
||||
drag = GDK_DRAG (drag_win32);
|
||||
|
||||
if (win32_display->has_fixed_scale)
|
||||
drag_win32->scale = win32_display->surface_scale;
|
||||
if (display_win32->has_fixed_scale)
|
||||
drag_win32->scale = display_win32->surface_scale;
|
||||
else
|
||||
drag_win32->scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, NULL, NULL, NULL);
|
||||
drag_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
|
||||
drag_win32->protocol = protocol;
|
||||
|
||||
@@ -2196,7 +2198,7 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
|
||||
id = g_timeout_add_full (G_PRIORITY_DEFAULT, 17,
|
||||
gdk_drag_anim_timeout, anim,
|
||||
(GDestroyNotify) gdk_drag_anim_destroy);
|
||||
g_source_set_name_by_id (id, "[gtk] gdk_drag_anim_timeout");
|
||||
gdk_source_set_static_name_by_id (id, "[gtk] gdk_drag_anim_timeout");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -177,7 +177,7 @@ gdk_drop_new (GdkDisplay *display,
|
||||
GdkDragProtocol protocol)
|
||||
{
|
||||
GdkWin32Drop *drop_win32;
|
||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||
GdkWin32Display *display_win32 = 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 (win32_display->has_fixed_scale)
|
||||
drop_win32->scale = win32_display->surface_scale;
|
||||
if (display_win32->has_fixed_scale)
|
||||
drop_win32->scale = display_win32->surface_scale;
|
||||
else
|
||||
drop_win32->scale = _gdk_win32_display_get_monitor_scale_factor (win32_display, NULL, NULL, NULL);
|
||||
drop_win32->scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
|
||||
drop_win32->protocol = protocol;
|
||||
|
||||
|
||||
+22
-64
@@ -55,14 +55,13 @@
|
||||
#include "gdkdevicemanager-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevice-virtual.h"
|
||||
#include "gdkdevice-wintab.h"
|
||||
#include "gdkinput-winpointer.h"
|
||||
#include "gdkwin32dnd.h"
|
||||
#include "gdkwin32dnd-private.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
//#include "gdkselection-win32.h"
|
||||
#include "gdkdragprivate.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <windowsx.h>
|
||||
|
||||
@@ -72,9 +71,8 @@
|
||||
#endif
|
||||
|
||||
#include <objbase.h>
|
||||
|
||||
#include <imm.h>
|
||||
#include <tchar.h>
|
||||
#include <tpcshrd.h>
|
||||
|
||||
#define GDK_MOD2_MASK (1 << 4)
|
||||
|
||||
@@ -505,7 +503,7 @@ _gdk_events_init (GdkDisplay *display)
|
||||
#endif
|
||||
|
||||
source = g_source_new (&event_funcs, sizeof (GdkWin32EventSource));
|
||||
g_source_set_name (source, "GDK Win32 event source");
|
||||
g_source_set_static_name (source, "GDK Win32 event source");
|
||||
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
|
||||
|
||||
event_source = (GdkWin32EventSource *)source;
|
||||
@@ -1038,12 +1036,11 @@ do_show_window (GdkSurface *window, gboolean hide_window)
|
||||
|
||||
static void
|
||||
send_crossing_event (GdkDisplay *display,
|
||||
GdkDevice *physical_device,
|
||||
GdkSurface *window,
|
||||
GdkSurface *window,
|
||||
GdkEventType type,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType notify_type,
|
||||
GdkSurface *subwindow,
|
||||
GdkSurface *subwindow,
|
||||
POINT *screen_pt,
|
||||
GdkModifierType mask,
|
||||
guint32 time_)
|
||||
@@ -1070,18 +1067,16 @@ send_crossing_event (GdkDisplay *display,
|
||||
pt = *screen_pt;
|
||||
ScreenToClient (GDK_SURFACE_HWND (window), &pt);
|
||||
|
||||
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer, physical_device);
|
||||
|
||||
event = gdk_crossing_event_new (type,
|
||||
window,
|
||||
device_manager->core_pointer,
|
||||
time_,
|
||||
_gdk_win32_get_next_tick (time_),
|
||||
mask,
|
||||
pt.x / impl->surface_scale,
|
||||
pt.y / impl->surface_scale,
|
||||
mode,
|
||||
notify_type);
|
||||
|
||||
|
||||
_gdk_win32_append_event (event);
|
||||
}
|
||||
|
||||
@@ -1124,9 +1119,8 @@ find_common_ancestor (GdkSurface *win1,
|
||||
|
||||
void
|
||||
synthesize_crossing_events (GdkDisplay *display,
|
||||
GdkDevice *physical_device,
|
||||
GdkSurface *src,
|
||||
GdkSurface *dest,
|
||||
GdkSurface *src,
|
||||
GdkSurface *dest,
|
||||
GdkCrossingMode mode,
|
||||
POINT *screen_pt,
|
||||
GdkModifierType mask,
|
||||
@@ -1159,7 +1153,6 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
else
|
||||
notify_type = GDK_NOTIFY_ANCESTOR;
|
||||
send_crossing_event (display,
|
||||
physical_device,
|
||||
a, GDK_LEAVE_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1179,7 +1172,6 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
while (win != c && win != NULL)
|
||||
{
|
||||
send_crossing_event (display,
|
||||
physical_device,
|
||||
win, GDK_LEAVE_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1222,7 +1214,6 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
next = b;
|
||||
|
||||
send_crossing_event (display,
|
||||
physical_device,
|
||||
win, GDK_ENTER_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1242,7 +1233,6 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
notify_type = GDK_NOTIFY_INFERIOR;
|
||||
|
||||
send_crossing_event (display,
|
||||
physical_device,
|
||||
b, GDK_ENTER_NOTIFY,
|
||||
mode,
|
||||
notify_type,
|
||||
@@ -1536,9 +1526,6 @@ generate_button_event (GdkEventType type,
|
||||
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
|
||||
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
|
||||
|
||||
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
|
||||
_gdk_device_manager->system_pointer);
|
||||
|
||||
event = gdk_button_event_new (type,
|
||||
window,
|
||||
device_manager->core_pointer,
|
||||
@@ -2258,12 +2245,11 @@ gdk_event_translate (MSG *msg,
|
||||
}
|
||||
|
||||
synthesize_crossing_events (display,
|
||||
_gdk_device_manager->system_pointer,
|
||||
implicit_grab_surface, new_window,
|
||||
GDK_CROSSING_UNGRAB,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
msg->time,
|
||||
FALSE);
|
||||
g_set_object (&implicit_grab_surface, NULL);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
@@ -2323,12 +2309,11 @@ gdk_event_translate (MSG *msg,
|
||||
mouse_window ? GDK_SURFACE_HWND (mouse_window) : NULL,
|
||||
new_window ? GDK_SURFACE_HWND (new_window) : NULL));
|
||||
synthesize_crossing_events (display,
|
||||
_gdk_device_manager->system_pointer,
|
||||
mouse_window, new_window,
|
||||
GDK_CROSSING_NORMAL,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
msg->time,
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
mouse_window_ignored_leave = NULL;
|
||||
@@ -2366,9 +2351,6 @@ gdk_event_translate (MSG *msg,
|
||||
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
|
||||
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
|
||||
|
||||
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
|
||||
_gdk_device_manager->system_pointer);
|
||||
|
||||
event = gdk_motion_event_new (window,
|
||||
device_manager_win32->core_pointer,
|
||||
NULL,
|
||||
@@ -2419,12 +2401,11 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
if (!ignore_leave)
|
||||
synthesize_crossing_events (display,
|
||||
_gdk_device_manager->system_pointer,
|
||||
mouse_window, new_window,
|
||||
GDK_CROSSING_NORMAL,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
msg->time,
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
mouse_window_ignored_leave = ignore_leave ? new_window : NULL;
|
||||
@@ -2974,13 +2955,6 @@ gdk_event_translate (MSG *msg,
|
||||
*ret_valp = 0;
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
|
||||
gdk_winpointer_finalize_surface (window);
|
||||
|
||||
return_val = FALSE;
|
||||
break;
|
||||
|
||||
case WM_NCDESTROY:
|
||||
if ((pointer_grab != NULL && pointer_grab->surface == window) ||
|
||||
(keyboard_grab && keyboard_grab->surface == window))
|
||||
@@ -3061,15 +3035,12 @@ gdk_event_translate (MSG *msg,
|
||||
{
|
||||
gdk_synthesize_surface_state (window, 0, GDK_TOPLEVEL_STATE_FOCUSED);
|
||||
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINTAB)
|
||||
{
|
||||
/* Bring any tablet contexts to the top of the overlap order when
|
||||
* one of our windows is activated.
|
||||
* NOTE: It doesn't seem to work well if it is done in WM_ACTIVATEAPP
|
||||
* instead
|
||||
*/
|
||||
_gdk_wintab_set_tablet_active ();
|
||||
}
|
||||
/* Bring any tablet contexts to the top of the overlap order when
|
||||
* one of our windows is activated.
|
||||
* NOTE: It doesn't seem to work well if it is done in WM_ACTIVATEAPP
|
||||
* instead
|
||||
*/
|
||||
_gdk_input_set_tablet_active ();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -3086,16 +3057,6 @@ gdk_event_translate (MSG *msg,
|
||||
GET_Y_LPARAM (msg->lParam), ret_valp);
|
||||
break;
|
||||
|
||||
case WM_TABLET_QUERYSYSTEMGESTURESTATUS:
|
||||
*ret_valp = TABLET_DISABLE_PRESSANDHOLD |
|
||||
TABLET_DISABLE_PENTAPFEEDBACK |
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK |
|
||||
TABLET_DISABLE_FLICKS |
|
||||
TABLET_DISABLE_FLICKFALLBACKKEYS;
|
||||
return_val = TRUE;
|
||||
break;
|
||||
|
||||
|
||||
/* Handle WINTAB events here, as we know that the device manager will
|
||||
* use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
|
||||
* constants as case labels.
|
||||
@@ -3118,14 +3079,11 @@ gdk_event_translate (MSG *msg,
|
||||
/* Fall through */
|
||||
wintab:
|
||||
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINTAB)
|
||||
event = gdk_input_other_event (display, msg, window);
|
||||
if (event)
|
||||
{
|
||||
event = gdk_wintab_make_event (display, msg, window);
|
||||
if (event)
|
||||
{
|
||||
_gdk_win32_append_event (event);
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
_gdk_win32_append_event (event);
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,504 @@
|
||||
/* 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)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,727 @@
|
||||
/* 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;
|
||||
}
|
||||
+1
-1228
File diff suppressed because it is too large
Load Diff
@@ -35,24 +35,13 @@
|
||||
|
||||
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
|
||||
@@ -60,15 +49,33 @@ struct _GdkWin32GLContextClass
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
|
||||
GdkGLContext *
|
||||
_gdk_win32_surface_create_gl_context (GdkSurface *window,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
/* 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;
|
||||
|
||||
gboolean
|
||||
_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
void
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface);
|
||||
|
||||
|
||||
@@ -37,12 +37,14 @@ HINSTANCE _gdk_dll_hinstance;
|
||||
HINSTANCE _gdk_app_hmodule;
|
||||
|
||||
int _gdk_input_ignore_core;
|
||||
GdkWin32TabletInputAPI _gdk_win32_tablet_input_api;
|
||||
|
||||
HKL _gdk_input_locale;
|
||||
gboolean _gdk_input_locale_is_ime = FALSE;
|
||||
UINT _gdk_input_codepage;
|
||||
|
||||
int _gdk_input_ignore_wintab = FALSE;
|
||||
int _gdk_max_colors = 0;
|
||||
|
||||
GdkWin32ModalOpKind _modal_operation_in_progress = GDK_WIN32_MODAL_OP_NONE;
|
||||
HWND _modal_move_resize_window = NULL;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,41 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 the GTK team
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_INPUT_WINPOINTER_H__
|
||||
#define __GDK_INPUT_WINPOINTER_H__
|
||||
|
||||
gboolean gdk_winpointer_initialize (void);
|
||||
|
||||
void gdk_winpointer_initialize_surface (GdkSurface *surface);
|
||||
void gdk_winpointer_finalize_surface (GdkSurface *surface);
|
||||
|
||||
typedef void
|
||||
(*crossing_cb_t)(GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
POINT *screen_pt,
|
||||
guint32 time_);
|
||||
|
||||
gboolean gdk_winpointer_should_forward_message (MSG *msg);
|
||||
void gdk_winpointer_input_events (GdkWindow *window,
|
||||
crossing_cb_t crossing_cb,
|
||||
MSG *msg);
|
||||
gboolean gdk_winpointer_get_message_info (MSG *msg,
|
||||
GdkDevice **device,
|
||||
guint32 *time_);
|
||||
void gdk_winpointer_interaction_ended (MSG *msg);
|
||||
|
||||
#endif /* __GDK_INPUT_WINPOINTER_H__ */
|
||||
@@ -694,6 +694,7 @@ 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);
|
||||
|
||||
@@ -54,6 +54,11 @@ _gdk_win32_surfaceing_init (void)
|
||||
{
|
||||
char buf[10];
|
||||
|
||||
if (getenv ("GDK_IGNORE_WINTAB") != NULL)
|
||||
_gdk_input_ignore_wintab = TRUE;
|
||||
else if (getenv ("GDK_USE_WINTAB") != NULL)
|
||||
_gdk_input_ignore_wintab = FALSE;
|
||||
|
||||
if (gdk_synchronize)
|
||||
GdiSetBatchLimit (1);
|
||||
|
||||
|
||||
@@ -15,6 +15,22 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined (_WIN32_WINNT) && WIN32_WINNT < 0x0601
|
||||
# undef _WIN32_WINNT
|
||||
|
||||
# define _WIN32_WINNT 0x0601
|
||||
# ifdef WINVER
|
||||
# undef WINVER
|
||||
# endif
|
||||
# define WINVER _WIN32_WINNT
|
||||
#elif !defined (_WIN32_WINNT)
|
||||
# define _WIN32_WINNT 0x0601
|
||||
# ifdef WINVER
|
||||
# undef WINVER
|
||||
# endif
|
||||
# define WINVER _WIN32_WINNT
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkprivate-win32.h"
|
||||
@@ -665,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, NULL);
|
||||
scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, NULL);
|
||||
|
||||
/* acquire the scale using the monitor which the window is nearest on Windows 8.1+ */
|
||||
if (data->display->have_at_least_win81)
|
||||
@@ -679,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, hmonitor, NULL, NULL);
|
||||
scale = gdk_win32_display_get_monitor_scale_factor (data->display, NULL, hmonitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,15 @@
|
||||
#ifndef __GDK_PRIVATE_WIN32_H__
|
||||
#define __GDK_PRIVATE_WIN32_H__
|
||||
|
||||
#ifndef WINVER
|
||||
/* Vista or newer */
|
||||
#define WINVER 0x0600
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT WINVER
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkcursorprivate.h>
|
||||
#include <gdk/win32/gdksurface-win32.h>
|
||||
#include <gdk/win32/gdkwin32display.h>
|
||||
@@ -148,12 +157,6 @@ typedef enum
|
||||
GDK_DRAG_PROTO_LOCAL,
|
||||
} GdkDragProtocol;
|
||||
|
||||
typedef enum {
|
||||
GDK_WIN32_TABLET_INPUT_API_NONE = 0,
|
||||
GDK_WIN32_TABLET_INPUT_API_WINTAB,
|
||||
GDK_WIN32_TABLET_INPUT_API_WINPOINTER
|
||||
} GdkWin32TabletInputAPI;
|
||||
|
||||
GType _gdk_gc_win32_get_type (void);
|
||||
|
||||
gulong _gdk_win32_get_next_tick (gulong suggested_tick);
|
||||
@@ -274,7 +277,6 @@ extern HINSTANCE _gdk_dll_hinstance;
|
||||
extern HINSTANCE _gdk_app_hmodule;
|
||||
|
||||
extern int _gdk_input_ignore_core;
|
||||
extern GdkWin32TabletInputAPI _gdk_win32_tablet_input_api;
|
||||
|
||||
/* These are thread specific, but GDK/win32 works OK only when invoked
|
||||
* from a single thread anyway.
|
||||
@@ -311,6 +313,11 @@ extern HWND _modal_move_resize_window;
|
||||
void _gdk_win32_begin_modal_call (GdkWin32ModalOpKind kind);
|
||||
void _gdk_win32_end_modal_call (GdkWin32ModalOpKind kind);
|
||||
|
||||
|
||||
/* Options */
|
||||
extern gboolean _gdk_input_ignore_wintab;
|
||||
extern int _gdk_max_colors;
|
||||
|
||||
/* Convert a pixbuf to an HICON (or HCURSOR). Supports alpha under
|
||||
* Windows XP, thresholds alpha otherwise.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define _WIN32_WINNT 0x0600
|
||||
|
||||
#include "gdk.h"
|
||||
#include "gdkprivate-win32.h"
|
||||
#include "gdkwin32screen.h"
|
||||
@@ -76,8 +78,7 @@ 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,
|
||||
NULL,
|
||||
screen_win32->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||
NULL,
|
||||
NULL);
|
||||
else
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdkwin32surface.h"
|
||||
#include "gdkwin32cursor.h"
|
||||
#include "gdkinput-winpointer.h"
|
||||
#include "gdkglcontext-win32.h"
|
||||
#include "gdkdisplay-win32.h"
|
||||
#include "gdkdevice-win32.h"
|
||||
@@ -398,12 +397,13 @@ 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 +522,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, NULL);
|
||||
impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
|
||||
|
||||
dwExStyle = 0;
|
||||
owner = NULL;
|
||||
@@ -646,9 +646,6 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_gdk_win32_tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
|
||||
gdk_winpointer_initialize_surface (surface);
|
||||
|
||||
_gdk_win32_surface_enable_transparency (surface);
|
||||
_gdk_win32_surface_register_dnd (surface);
|
||||
|
||||
@@ -658,6 +655,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
impl);
|
||||
|
||||
g_object_unref (frame_clock);
|
||||
impl->hdc = GetDC (impl->handle);
|
||||
|
||||
return surface;
|
||||
}
|
||||
@@ -4430,19 +4428,19 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
|
||||
|
||||
|
||||
int
|
||||
_gdk_win32_surface_get_scale_factor (GdkSurface *window)
|
||||
_gdk_win32_surface_get_scale_factor (GdkSurface *surface)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkWin32Surface *impl;
|
||||
GdkWin32Display *win32_display;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return 1;
|
||||
|
||||
g_return_val_if_fail (window != NULL, 1);
|
||||
g_return_val_if_fail (surface != NULL, 1);
|
||||
|
||||
display = gdk_surface_get_display (window);
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
display = gdk_surface_get_display (surface);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
@@ -4451,9 +4449,8 @@ _gdk_win32_surface_get_scale_factor (GdkSurface *window)
|
||||
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,
|
||||
NULL,
|
||||
GDK_SURFACE_HWND (window),
|
||||
impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||
surface,
|
||||
NULL);
|
||||
|
||||
return impl->surface_scale;
|
||||
@@ -4627,7 +4624,6 @@ 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;
|
||||
@@ -5049,9 +5045,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);
|
||||
@@ -5070,7 +5066,10 @@ _gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||
else
|
||||
{
|
||||
if (impl->egl_surface == EGL_NO_SURFACE)
|
||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp, config, display->gl_hwnd, NULL);
|
||||
impl->egl_surface = eglCreateWindowSurface (display->egl_disp,
|
||||
config,
|
||||
GDK_SURFACE_HWND (surface),
|
||||
NULL);
|
||||
|
||||
return impl->egl_surface;
|
||||
}
|
||||
@@ -5153,3 +5152,20 @@ 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
|
||||
|
||||
+11
-19
@@ -6,7 +6,6 @@ gdk_win32_sources = files([
|
||||
'gdkdevicemanager-win32.c',
|
||||
'gdkdevice-virtual.c',
|
||||
'gdkdevice-win32.c',
|
||||
'gdkdevice-winpointer.c',
|
||||
'gdkdevice-wintab.c',
|
||||
'gdkdisplay-win32.c',
|
||||
'gdkdisplaymanager-win32.c',
|
||||
@@ -14,9 +13,9 @@ gdk_win32_sources = files([
|
||||
'gdkdrop-win32.c',
|
||||
'gdkevents-win32.c',
|
||||
'gdkglcontext-win32.c',
|
||||
'gdkglcontext-win32-wgl.c',
|
||||
'gdkglobals-win32.c',
|
||||
'gdkhdataoutputstream-win32.c',
|
||||
'gdkinput-winpointer.c',
|
||||
'gdkkeys-win32.c',
|
||||
'gdkwin32langnotification.c',
|
||||
'gdkmain-win32.c',
|
||||
@@ -45,31 +44,24 @@ gdk_win32_public_headers = files([
|
||||
|
||||
install_headers(gdk_win32_public_headers, 'gdkwin32.h', subdir: 'gtk-4.0/gdk/win32/')
|
||||
|
||||
gdk_win32_cflags = [
|
||||
'-DGTK_COMPILATION',
|
||||
'-DG_LOG_DOMAIN="Gdk"',
|
||||
'-DINSIDE_GDK_WIN32',
|
||||
]
|
||||
|
||||
gdk_win32_cflags += [
|
||||
'-D_WIN32_WINNT=0x0602', # Windows 8
|
||||
'-Isdkddkver.h',
|
||||
]
|
||||
GDK_WIN32_EGL_CFLAGS = []
|
||||
|
||||
if win32_has_egl
|
||||
gdk_win32_cflags += [
|
||||
'-DGDK_WIN32_ENABLE_EGL'
|
||||
]
|
||||
GDK_WIN32_EGL_CFLAGS = ['-DGDK_WIN32_ENABLE_EGL']
|
||||
gdk_win32_sources += ['gdkglcontext-win32-egl.c']
|
||||
endif
|
||||
|
||||
gdk_win32_deps = [
|
||||
pangowin32_dep, # FIXME
|
||||
cc.find_library('hid'),
|
||||
gdk_win32_deps = [ # FIXME
|
||||
pangowin32_dep
|
||||
]
|
||||
|
||||
libgdk_win32 = static_library('gdk-win32',
|
||||
gdk_win32_sources, gdkconfig, gdkenum_h,
|
||||
include_directories: [ confinc, gdkinc ],
|
||||
c_args: gdk_win32_cflags,
|
||||
c_args: [
|
||||
'-DGTK_COMPILATION',
|
||||
'-DG_LOG_DOMAIN="Gdk"',
|
||||
'-DINSIDE_GDK_WIN32',
|
||||
] + GDK_WIN32_EGL_CFLAGS,
|
||||
dependencies: [ gdk_deps, gdk_win32_deps ],
|
||||
)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "gdkintl.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkdisplay-x11.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <glib.h>
|
||||
#ifdef HAVE_DESKTOPAPPINFO
|
||||
@@ -219,7 +220,7 @@ startup_timeout (void *data)
|
||||
std->timeout_id = 0;
|
||||
else {
|
||||
std->timeout_id = g_timeout_add_seconds ((min_timeout + 500)/1000, startup_timeout, std);
|
||||
g_source_set_name_by_id (std->timeout_id, "[gtk] startup_timeout");
|
||||
gdk_source_set_static_name_by_id (std->timeout_id, "[gtk] startup_timeout");
|
||||
}
|
||||
|
||||
/* always remove this one, but we may have reinstalled another one. */
|
||||
@@ -256,7 +257,7 @@ add_startup_timeout (GdkX11Screen *screen,
|
||||
if (data->timeout_id == 0) {
|
||||
data->timeout_id = g_timeout_add_seconds (STARTUP_TIMEOUT_LENGTH_SECONDS,
|
||||
startup_timeout, data);
|
||||
g_source_set_name_by_id (data->timeout_id, "[gtk] startup_timeout");
|
||||
gdk_source_set_static_name_by_id (data->timeout_id, "[gtk] startup_timeout");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -46,6 +46,7 @@ in this Software without prior written authorization from The Open Group.
|
||||
#include "gdkasync.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkdisplay-x11.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <X11/Xlibint.h>
|
||||
|
||||
@@ -171,7 +172,7 @@ send_event_handler (Display *dpy,
|
||||
{
|
||||
guint id;
|
||||
id = g_idle_add (callback_idle, state);
|
||||
g_source_set_name_by_id (id, "[gtk] callback_idle");
|
||||
gdk_source_set_static_name_by_id (id, "[gtk] callback_idle");
|
||||
}
|
||||
|
||||
DeqAsyncHandler(state->dpy, &state->async);
|
||||
@@ -707,7 +708,7 @@ roundtrip_handler (Display *dpy,
|
||||
{
|
||||
guint id;
|
||||
id = g_idle_add (roundtrip_callback_idle, state);
|
||||
g_source_set_name_by_id (id, "[gtk] roundtrip_callback_idle");
|
||||
gdk_source_set_static_name_by_id (id, "[gtk] roundtrip_callback_idle");
|
||||
}
|
||||
|
||||
DeqAsyncHandler(state->dpy, &state->async);
|
||||
|
||||
+130
-101
@@ -69,10 +69,6 @@
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
@@ -1339,20 +1335,70 @@ set_sm_client_id (GdkDisplay *display,
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_setup_window_visual (GdkDisplay *display,
|
||||
int depth,
|
||||
Visual *visual,
|
||||
Colormap colormap,
|
||||
gboolean rgba)
|
||||
static void
|
||||
gdk_x11_display_query_default_visual (GdkX11Display *self,
|
||||
Visual **out_visual,
|
||||
int *out_depth)
|
||||
{
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
XVisualInfo template, *visinfo;
|
||||
int n_visuals;
|
||||
Display *dpy;
|
||||
|
||||
display_x11->window_depth = depth;
|
||||
display_x11->window_visual = visual;
|
||||
display_x11->window_colormap = colormap;
|
||||
dpy = gdk_x11_display_get_xdisplay (GDK_DISPLAY (self));
|
||||
|
||||
gdk_display_set_rgba (display, rgba);
|
||||
template.screen = self->screen->screen_num;
|
||||
template.depth = 32;
|
||||
template.red_mask = 0xff0000;
|
||||
template.green_mask = 0x00ff00;
|
||||
template.blue_mask = 0x0000ff;
|
||||
|
||||
visinfo = XGetVisualInfo (dpy,
|
||||
VisualScreenMask | VisualDepthMask
|
||||
| VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
|
||||
&template,
|
||||
&n_visuals);
|
||||
if (visinfo != NULL)
|
||||
{
|
||||
*out_visual = visinfo[0].visual;
|
||||
*out_depth = visinfo[0].depth;
|
||||
XFree (visinfo);
|
||||
return;
|
||||
}
|
||||
|
||||
*out_visual = DefaultVisual (dpy, self->screen->screen_num);
|
||||
*out_depth = DefaultDepth (dpy, self->screen->screen_num);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_display_init_leader_surface (GdkX11Display *self)
|
||||
{
|
||||
GdkDisplay *display = GDK_DISPLAY (self);
|
||||
Display *xdisplay = gdk_x11_display_get_xdisplay (display);
|
||||
|
||||
self->window_colormap = XCreateColormap (xdisplay,
|
||||
DefaultRootWindow (xdisplay),
|
||||
self->window_visual,
|
||||
AllocNone);
|
||||
gdk_display_set_rgba (display, self->window_depth == 32);
|
||||
|
||||
/* We need to initialize events after we have the screen
|
||||
* structures in places
|
||||
*/
|
||||
_gdk_x11_xsettings_init (GDK_X11_SCREEN (self->screen));
|
||||
|
||||
self->device_manager = _gdk_x11_device_manager_new (display);
|
||||
|
||||
gdk_event_init (display);
|
||||
|
||||
self->leader_gdk_surface =
|
||||
_gdk_x11_display_create_surface (display,
|
||||
GDK_SURFACE_TEMP,
|
||||
NULL,
|
||||
-100, -100, 1, 1);
|
||||
|
||||
(_gdk_x11_surface_get_toplevel (self->leader_gdk_surface))->is_leader = TRUE;
|
||||
self->leader_window = GDK_SURFACE_XID (self->leader_gdk_surface);
|
||||
self->leader_window_title_set = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1420,28 +1466,20 @@ gdk_x11_display_open (const char *display_name)
|
||||
#endif
|
||||
|
||||
/* initialize the display's screens */
|
||||
display_x11->screen = _gdk_x11_screen_new (display, DefaultScreen (display_x11->xdisplay), TRUE);
|
||||
display_x11->screen = _gdk_x11_screen_new (display, DefaultScreen (display_x11->xdisplay));
|
||||
|
||||
/* We need to initialize events after we have the screen
|
||||
* structures in places
|
||||
/* If GL is available we want to pick better default/rgba visuals,
|
||||
* as we care about GLX details such as alpha/depth/stencil depth,
|
||||
* stereo and double buffering
|
||||
*
|
||||
* Note that this also sets up the leader surface while creating the inital
|
||||
* GL context.
|
||||
*/
|
||||
_gdk_x11_xsettings_init (GDK_X11_SCREEN (display_x11->screen));
|
||||
|
||||
display_x11->device_manager = _gdk_x11_device_manager_new (display);
|
||||
|
||||
gdk_event_init (display);
|
||||
|
||||
display_x11->leader_gdk_surface =
|
||||
_gdk_x11_display_create_surface (display,
|
||||
GDK_SURFACE_TEMP,
|
||||
NULL,
|
||||
-100, -100, 1, 1);
|
||||
|
||||
(_gdk_x11_surface_get_toplevel (display_x11->leader_gdk_surface))->is_leader = TRUE;
|
||||
|
||||
display_x11->leader_window = GDK_SURFACE_XID (display_x11->leader_gdk_surface);
|
||||
|
||||
display_x11->leader_window_title_set = FALSE;
|
||||
if (!gdk_display_prepare_gl (display, NULL))
|
||||
{
|
||||
gdk_x11_display_query_default_visual (display_x11, &display_x11->window_visual, &display_x11->window_depth);
|
||||
gdk_x11_display_init_leader_surface (display_x11);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XFIXES
|
||||
if (XFixesQueryExtension (display_x11->xdisplay,
|
||||
@@ -1454,24 +1492,6 @@ gdk_x11_display_open (const char *display_name)
|
||||
#endif
|
||||
display_x11->have_xfixes = FALSE;
|
||||
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
if (XCompositeQueryExtension (display_x11->xdisplay,
|
||||
&ignore, &ignore))
|
||||
{
|
||||
int major, minor;
|
||||
|
||||
XCompositeQueryVersion (display_x11->xdisplay, &major, &minor);
|
||||
|
||||
/* Prior to Composite version 0.4, composited windows clipped their
|
||||
* parents, so you had to use IncludeInferiors to draw to the parent
|
||||
* This isn't useful for our purposes, so require 0.4
|
||||
*/
|
||||
display_x11->have_xcomposite = major > 0 || (major == 0 && minor >= 4);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
display_x11->have_xcomposite = FALSE;
|
||||
|
||||
display_x11->have_shapes = FALSE;
|
||||
display_x11->have_input_shapes = FALSE;
|
||||
|
||||
@@ -1928,7 +1948,6 @@ gdk_x11_display_finalize (GObject *object)
|
||||
|
||||
/* Free all GdkX11Screens */
|
||||
g_object_unref (display_x11->screen);
|
||||
g_list_free_full (display_x11->screens, g_object_unref);
|
||||
|
||||
g_list_store_remove_all (display_x11->monitors);
|
||||
g_object_unref (display_x11->monitors);
|
||||
@@ -1940,6 +1959,8 @@ gdk_x11_display_finalize (GObject *object)
|
||||
|
||||
XCloseDisplay (display_x11->xdisplay);
|
||||
|
||||
g_clear_error (&display_x11->gl_error);
|
||||
|
||||
/* error traps */
|
||||
while (display_x11->error_traps != NULL)
|
||||
{
|
||||
@@ -1993,52 +2014,6 @@ gdk_x11_lookup_xdisplay (Display *xdisplay)
|
||||
return display;
|
||||
}
|
||||
|
||||
/*
|
||||
* _gdk_x11_display_screen_for_xrootwin:
|
||||
* @display: a `GdkDisplay`
|
||||
* @xrootwin: window ID for one of the screen’s of the display.
|
||||
*
|
||||
* Given the root window ID of one of the screen’s of a `GdkDisplay`,
|
||||
* finds the screen.
|
||||
*
|
||||
* Returns: (transfer none): the `GdkX11Screen` corresponding to @xrootwin
|
||||
*/
|
||||
GdkX11Screen *
|
||||
_gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
|
||||
Window xrootwin)
|
||||
{
|
||||
GdkX11Screen *screen;
|
||||
XWindowAttributes attrs;
|
||||
gboolean result;
|
||||
GdkX11Display *display_x11;
|
||||
GList *l;
|
||||
|
||||
screen = GDK_X11_DISPLAY (display)->screen;
|
||||
|
||||
if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
|
||||
return screen;
|
||||
|
||||
display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
for (l = display_x11->screens; l; l = l->next)
|
||||
{
|
||||
screen = l->data;
|
||||
if (GDK_SCREEN_XROOTWIN (screen) == xrootwin)
|
||||
return screen;
|
||||
}
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
result = XGetWindowAttributes (display_x11->xdisplay, xrootwin, &attrs);
|
||||
if (gdk_x11_display_error_trap_pop (display) || !result)
|
||||
return NULL;
|
||||
|
||||
screen = _gdk_x11_screen_new (display, XScreenNumberOfScreen (attrs.screen), FALSE);
|
||||
|
||||
display_x11->screens = g_list_prepend (display_x11->screens, screen);
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_display_get_xdisplay:
|
||||
* @display: (type GdkX11Display): a `GdkDisplay`
|
||||
@@ -2910,6 +2885,60 @@ gdk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
|
||||
return continue_emission;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_display_init_gl_backend (GdkX11Display *self,
|
||||
Visual **out_visual,
|
||||
int *out_depth,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display G_GNUC_UNUSED = GDK_DISPLAY (self);
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_EGL))
|
||||
return gdk_x11_display_init_egl (self, TRUE, out_visual, out_depth, error);
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_GLX))
|
||||
return gdk_x11_display_init_glx (self, out_visual, out_depth, error);
|
||||
|
||||
/* No env vars set, do the regular GL initialization.
|
||||
*
|
||||
* We try EGL first, but are very picky about what we accept.
|
||||
* If that fails, we try to go with GLX instead.
|
||||
* And if that also fails, we try EGL again, but this time accept anything.
|
||||
*
|
||||
* The idea here is that EGL is the preferred method going forward, but GLX is
|
||||
* the tried and tested method that we know works. So if we detect issues with
|
||||
* EGL, we want to avoid using it in favor of GLX.
|
||||
*/
|
||||
|
||||
if (gdk_x11_display_init_egl (self, FALSE, out_visual, out_depth, error))
|
||||
return TRUE;
|
||||
g_clear_error (error);
|
||||
|
||||
if (gdk_x11_display_init_glx (self, out_visual, out_depth, error))
|
||||
return TRUE;
|
||||
g_clear_error (error);
|
||||
|
||||
return gdk_x11_display_init_egl (self, TRUE, out_visual, out_depth, error);
|
||||
}
|
||||
|
||||
static GdkGLContext *
|
||||
gdk_x11_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
GdkX11Display *self = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (!gdk_x11_display_init_gl_backend (self, &self->window_visual, &self->window_depth, error))
|
||||
return FALSE;
|
||||
|
||||
gdk_x11_display_init_leader_surface (self);
|
||||
|
||||
if (self->egl_display)
|
||||
return g_object_new (GDK_TYPE_X11_GL_CONTEXT_EGL, "surface", self->leader_gdk_surface, NULL);
|
||||
else if (self->glx_config != NULL)
|
||||
return g_object_new (GDK_TYPE_X11_GL_CONTEXT_GLX, "surface", self->leader_gdk_surface, NULL);
|
||||
else
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
{
|
||||
@@ -2940,7 +2969,7 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
display_class->create_surface = _gdk_x11_display_create_surface;
|
||||
display_class->get_keymap = gdk_x11_display_get_keymap;
|
||||
|
||||
display_class->make_gl_context_current = gdk_x11_display_make_gl_context_current;
|
||||
display_class->init_gl = gdk_x11_display_init_gl;
|
||||
|
||||
display_class->get_default_seat = gdk_x11_display_get_default_seat;
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ struct _GdkX11Display
|
||||
GdkDisplay parent_instance;
|
||||
Display *xdisplay;
|
||||
GdkX11Screen *screen;
|
||||
GList *screens;
|
||||
GList *toplevels;
|
||||
GdkX11DeviceManagerXI2 *device_manager;
|
||||
|
||||
@@ -71,8 +70,6 @@ struct _GdkX11Display
|
||||
gboolean have_xfixes;
|
||||
int xfixes_event_base;
|
||||
|
||||
gboolean have_xcomposite;
|
||||
|
||||
gboolean have_randr12;
|
||||
gboolean have_randr13;
|
||||
gboolean have_randr15;
|
||||
@@ -132,12 +129,17 @@ struct _GdkX11Display
|
||||
guint have_damage;
|
||||
#endif
|
||||
|
||||
/* If GL is not supported, store the error here */
|
||||
GError *gl_error;
|
||||
|
||||
/* GLX information */
|
||||
/* GLXFBConfig */ gpointer glx_config;
|
||||
int glx_version;
|
||||
int glx_error_base;
|
||||
int glx_event_base;
|
||||
|
||||
/* EGL information */
|
||||
/* We use gpointer here so we don't have to pull in EGL headers (which glx doesn't like) */
|
||||
/* EGLDisplay */ gpointer egl_display;
|
||||
/* EGLConfig */ gpointer egl_config;
|
||||
int egl_version;
|
||||
|
||||
/* Translation between X server time and system-local monotonic time */
|
||||
@@ -146,9 +148,6 @@ struct _GdkX11Display
|
||||
|
||||
guint server_time_is_monotonic_time : 1;
|
||||
|
||||
guint have_glx : 1;
|
||||
guint have_egl : 1;
|
||||
|
||||
/* GLX extensions we check */
|
||||
guint has_glx_swap_interval : 1;
|
||||
guint has_glx_create_context : 1;
|
||||
@@ -165,7 +164,6 @@ struct _GdkX11Display
|
||||
guint has_egl_khr_create_context : 1;
|
||||
guint has_egl_buffer_age : 1;
|
||||
guint has_egl_swap_buffers_with_damage : 1;
|
||||
guint has_egl_surfaceless_context : 1;
|
||||
};
|
||||
|
||||
struct _GdkX11DisplayClass
|
||||
@@ -176,8 +174,6 @@ struct _GdkX11DisplayClass
|
||||
const XEvent *event);
|
||||
};
|
||||
|
||||
GdkX11Screen * _gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
|
||||
Window xrootwin);
|
||||
void _gdk_x11_display_error_event (GdkDisplay *display,
|
||||
XErrorEvent *error);
|
||||
gsize gdk_x11_display_get_max_request_size (GdkDisplay *display);
|
||||
|
||||
+3
-28
@@ -47,9 +47,6 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -518,9 +515,6 @@ gdk_surface_cache_new (GdkDisplay *display)
|
||||
Window xroot_window = GDK_DISPLAY_XROOTWIN (display);
|
||||
GdkChildInfoX11 *children;
|
||||
guint nchildren, i;
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
Window cow;
|
||||
#endif
|
||||
|
||||
GdkSurfaceCache *result = g_new (GdkSurfaceCache, 1);
|
||||
|
||||
@@ -571,27 +565,6 @@ gdk_surface_cache_new (GdkDisplay *display)
|
||||
|
||||
g_free (children);
|
||||
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
/*
|
||||
* Add the composite overlay window to the cache, as this can be a reasonable
|
||||
* Xdnd proxy as well.
|
||||
* This is only done when the screen is composited in order to avoid mapping
|
||||
* the COW. We assume that the CM is using the COW (which is true for pretty
|
||||
* much any CM currently in use).
|
||||
*/
|
||||
if (gdk_display_is_composited (display))
|
||||
{
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
cow = XCompositeGetOverlayWindow (xdisplay, xroot_window);
|
||||
gdk_surface_cache_add (result, cow, 0, 0,
|
||||
WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen),
|
||||
HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen),
|
||||
TRUE);
|
||||
XCompositeReleaseOverlayWindow (xdisplay, xroot_window);
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -911,8 +884,10 @@ gdk_x11_drag_handle_finished (GdkDisplay *display,
|
||||
if (drag_x11->version == 5)
|
||||
drag_x11->drop_failed = xevent->xclient.data.l[1] == 0;
|
||||
|
||||
g_object_ref (drag);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, !drag_x11->drop_failed);
|
||||
g_object_unref (drag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1889,7 +1864,7 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
|
||||
id = g_timeout_add_full (G_PRIORITY_DEFAULT, 17,
|
||||
gdk_drag_anim_timeout, anim,
|
||||
(GDestroyNotify) gdk_drag_anim_destroy);
|
||||
g_source_set_name_by_id (id, "[gtk] gdk_drag_anim_timeout");
|
||||
gdk_source_set_static_name_by_id (id, "[gtk] gdk_drag_anim_timeout");
|
||||
g_object_unref (drag);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +45,6 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
+375
-405
@@ -19,7 +19,6 @@
|
||||
#include "gdkx11glcontext.h"
|
||||
#include "gdkx11screen.h"
|
||||
#include "gdkx11surface.h"
|
||||
#include "gdkvisual-x11.h"
|
||||
#include "gdkx11property.h"
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
@@ -35,55 +34,15 @@ struct _GdkX11GLContextEGL
|
||||
{
|
||||
GdkX11GLContext parent_instance;
|
||||
|
||||
EGLDisplay egl_display;
|
||||
EGLConfig egl_config;
|
||||
EGLContext egl_context;
|
||||
|
||||
guint do_frame_sync : 1;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
EGLDisplay egl_display;
|
||||
EGLConfig egl_config;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
/* Only set by the dummy surface we attach to the display */
|
||||
Display *xdisplay;
|
||||
Window dummy_xwin;
|
||||
XVisualInfo *xvisinfo;
|
||||
} DrawableInfo;
|
||||
|
||||
typedef struct _GdkX11GLContextClass GdkX11GLContextEGLClass;
|
||||
|
||||
G_DEFINE_TYPE (GdkX11GLContextEGL, gdk_x11_gl_context_egl, GDK_TYPE_X11_GL_CONTEXT)
|
||||
|
||||
static void
|
||||
drawable_info_free (gpointer data)
|
||||
{
|
||||
DrawableInfo *info = data;
|
||||
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
||||
if (info->egl_surface != NULL)
|
||||
{
|
||||
eglDestroySurface (info->egl_display, info->egl_surface);
|
||||
info->egl_surface = NULL;
|
||||
}
|
||||
|
||||
if (info->dummy_xwin != None)
|
||||
{
|
||||
XDestroyWindow (info->xdisplay, info->dummy_xwin);
|
||||
info->dummy_xwin = None;
|
||||
}
|
||||
|
||||
if (info->xvisinfo != NULL)
|
||||
{
|
||||
XFree (info->xvisinfo);
|
||||
info->xvisinfo = NULL;
|
||||
}
|
||||
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_display_get_egl_display:
|
||||
* @display: (type GdkX11Display): an X11 display
|
||||
@@ -99,19 +58,23 @@ drawable_info_free (gpointer data)
|
||||
gpointer
|
||||
gdk_x11_display_get_egl_display (GdkDisplay *display)
|
||||
{
|
||||
EGLDisplay edpy = NULL;
|
||||
Display *dpy;
|
||||
GdkX11Display *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_X11_DISPLAY (display), NULL);
|
||||
|
||||
if (GDK_X11_DISPLAY (display)->have_glx)
|
||||
return NULL;
|
||||
self = GDK_X11_DISPLAY (display);
|
||||
|
||||
edpy = g_object_get_data (G_OBJECT (display), "-gdk-x11-egl-display");
|
||||
if (edpy != NULL)
|
||||
return edpy;
|
||||
return self->egl_display;
|
||||
}
|
||||
|
||||
dpy = gdk_x11_display_get_xdisplay (display);
|
||||
static void
|
||||
gdk_x11_display_create_egl_display (GdkX11Display *self)
|
||||
{
|
||||
Display *dpy;
|
||||
|
||||
g_assert (self->egl_display == NULL);
|
||||
|
||||
dpy = gdk_x11_display_get_xdisplay (GDK_DISPLAY (self));
|
||||
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_KHR_platform_base"))
|
||||
{
|
||||
@@ -119,10 +82,10 @@ gdk_x11_display_get_egl_display (GdkDisplay *display)
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplay");
|
||||
|
||||
if (getPlatformDisplay != NULL)
|
||||
edpy = getPlatformDisplay (EGL_PLATFORM_X11_KHR, dpy, NULL);
|
||||
self->egl_display = getPlatformDisplay (EGL_PLATFORM_X11_KHR, dpy, NULL);
|
||||
|
||||
if (edpy != NULL)
|
||||
goto out;
|
||||
if (self->egl_display != NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
|
||||
@@ -131,145 +94,231 @@ gdk_x11_display_get_egl_display (GdkDisplay *display)
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
|
||||
|
||||
if (getPlatformDisplay)
|
||||
edpy = getPlatformDisplay (EGL_PLATFORM_X11_EXT, dpy, NULL);
|
||||
self->egl_display = getPlatformDisplay (EGL_PLATFORM_X11_EXT, dpy, NULL);
|
||||
|
||||
if (edpy != NULL)
|
||||
goto out;
|
||||
if (self->egl_display != NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
edpy = eglGetDisplay ((EGLNativeDisplayType) dpy);
|
||||
|
||||
out:
|
||||
if (edpy != NULL)
|
||||
g_object_set_data (G_OBJECT (display), "-gdk-x11-egl-display", edpy);
|
||||
|
||||
return edpy;
|
||||
self->egl_display = eglGetDisplay ((EGLNativeDisplayType) dpy);
|
||||
}
|
||||
|
||||
static XVisualInfo *
|
||||
get_visual_info_for_egl_config (GdkDisplay *display,
|
||||
EGLConfig egl_config)
|
||||
gdk_x11_display_get_visual_info_for_visual (GdkX11Display *self,
|
||||
VisualID visualid)
|
||||
{
|
||||
XVisualInfo visinfo_template;
|
||||
int template_mask = 0;
|
||||
XVisualInfo *visinfo = NULL;
|
||||
int visinfos_count;
|
||||
EGLint visualid, red_size, green_size, blue_size, alpha_size;
|
||||
EGLDisplay egl_display = gdk_x11_display_get_egl_display (display);
|
||||
XVisualInfo template, *visinfo;
|
||||
int nvisuals;
|
||||
|
||||
eglGetConfigAttrib (egl_display, egl_config, EGL_NATIVE_VISUAL_ID, &visualid);
|
||||
|
||||
if (visualid != 0)
|
||||
{
|
||||
visinfo_template.visualid = visualid;
|
||||
template_mask |= VisualIDMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID
|
||||
* attribute, so attempt to find the closest match.
|
||||
*/
|
||||
eglGetConfigAttrib (egl_display, egl_config, EGL_RED_SIZE, &red_size);
|
||||
eglGetConfigAttrib (egl_display, egl_config, EGL_GREEN_SIZE, &green_size);
|
||||
eglGetConfigAttrib (egl_display, egl_config, EGL_BLUE_SIZE, &blue_size);
|
||||
eglGetConfigAttrib (egl_display, egl_config, EGL_ALPHA_SIZE, &alpha_size);
|
||||
|
||||
visinfo_template.depth = red_size + green_size + blue_size + alpha_size;
|
||||
template_mask |= VisualDepthMask;
|
||||
|
||||
visinfo_template.screen = DefaultScreen (gdk_x11_display_get_xdisplay (display));
|
||||
template_mask |= VisualScreenMask;
|
||||
}
|
||||
|
||||
visinfo = XGetVisualInfo (gdk_x11_display_get_xdisplay (display),
|
||||
template_mask,
|
||||
&visinfo_template,
|
||||
&visinfos_count);
|
||||
|
||||
if (visinfos_count < 1)
|
||||
return NULL;
|
||||
template.screen = self->screen->screen_num;
|
||||
template.visualid = visualid;
|
||||
|
||||
visinfo = XGetVisualInfo (gdk_x11_display_get_xdisplay (GDK_DISPLAY (self)),
|
||||
VisualScreenMask | VisualIDMask,
|
||||
&template,
|
||||
&nvisuals);
|
||||
g_warn_if_fail (nvisuals == 1);
|
||||
|
||||
return visinfo;
|
||||
}
|
||||
|
||||
static EGLSurface
|
||||
gdk_x11_display_get_egl_dummy_surface (GdkDisplay *display,
|
||||
EGLConfig egl_config)
|
||||
static gboolean
|
||||
visual_is_rgba (XVisualInfo *visinfo)
|
||||
{
|
||||
DrawableInfo *info;
|
||||
XVisualInfo *xvisinfo;
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
info = g_object_get_data (G_OBJECT (display), "-gdk-x11-egl-dummy-surface");
|
||||
if (info != NULL)
|
||||
return info->egl_surface;
|
||||
|
||||
xvisinfo = get_visual_info_for_egl_config (display, egl_config);
|
||||
if (xvisinfo == NULL)
|
||||
return NULL;
|
||||
|
||||
info = g_new (DrawableInfo, 1);
|
||||
info->xdisplay = gdk_x11_display_get_xdisplay (display);
|
||||
info->xvisinfo = xvisinfo;
|
||||
info->egl_display = gdk_x11_display_get_egl_display (display);
|
||||
info->egl_config = egl_config;
|
||||
|
||||
attrs.override_redirect = True;
|
||||
attrs.colormap = XCreateColormap (info->xdisplay,
|
||||
DefaultRootWindow (info->xdisplay),
|
||||
xvisinfo->visual,
|
||||
AllocNone);
|
||||
attrs.border_pixel = 0;
|
||||
|
||||
info->dummy_xwin =
|
||||
XCreateWindow (info->xdisplay,
|
||||
DefaultRootWindow (info->xdisplay),
|
||||
-100, -100, 1, 1,
|
||||
0,
|
||||
xvisinfo->depth,
|
||||
CopyFromParent,
|
||||
xvisinfo->visual,
|
||||
CWOverrideRedirect | CWColormap | CWBorderPixel,
|
||||
&attrs);
|
||||
|
||||
info->egl_surface =
|
||||
eglCreateWindowSurface (info->egl_display,
|
||||
info->egl_config,
|
||||
(EGLNativeWindowType) info->dummy_xwin,
|
||||
NULL);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (display), "-gdk-x11-egl-dummy-surface",
|
||||
info,
|
||||
drawable_info_free);
|
||||
|
||||
return info->egl_surface;
|
||||
return
|
||||
visinfo->depth == 32 &&
|
||||
visinfo->visual->red_mask == 0xff0000 &&
|
||||
visinfo->visual->green_mask == 0x00ff00 &&
|
||||
visinfo->visual->blue_mask == 0x0000ff;
|
||||
}
|
||||
|
||||
static EGLSurface
|
||||
gdk_x11_surface_get_egl_surface (GdkSurface *surface,
|
||||
EGLConfig config)
|
||||
#define MAX_EGL_ATTRS 30
|
||||
|
||||
static gboolean
|
||||
gdk_x11_display_create_egl_config (GdkX11Display *display,
|
||||
gboolean force,
|
||||
Visual **out_visual,
|
||||
int *out_depth,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
EGLDisplay egl_display = gdk_x11_display_get_egl_display (display);
|
||||
DrawableInfo *info;
|
||||
GdkX11Display *self = GDK_X11_DISPLAY (display);
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLConfig *configs;
|
||||
EGLint count, alloced;
|
||||
enum {
|
||||
NO_VISUAL_FOUND,
|
||||
WITH_MULTISAMPLING,
|
||||
WITH_STENCIL_AND_DEPTH_BUFFER,
|
||||
NO_ALPHA,
|
||||
NO_ALPHA_VISUAL,
|
||||
PERFECT
|
||||
} best_features;
|
||||
|
||||
info = g_object_get_data (G_OBJECT (surface), "-gdk-x11-egl-drawable");
|
||||
if (info != NULL)
|
||||
return info->egl_surface;
|
||||
int i = 0;
|
||||
|
||||
info = g_new0 (DrawableInfo, 1);
|
||||
info->egl_display = egl_display;
|
||||
info->egl_config = config;
|
||||
info->egl_surface =
|
||||
eglCreateWindowSurface (info->egl_display, config,
|
||||
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++] = 8;
|
||||
attrs[i++] = EGL_GREEN_SIZE;
|
||||
attrs[i++] = 8;
|
||||
attrs[i++] = EGL_BLUE_SIZE;
|
||||
attrs[i++] = 8;
|
||||
attrs[i++] = EGL_ALPHA_SIZE;
|
||||
attrs[i++] = 8;
|
||||
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
if (!eglChooseConfig (self->egl_display, attrs, NULL, -1, &alloced) || alloced == 0)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No EGL configuration available"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
configs = g_new (EGLConfig, alloced);
|
||||
if (!eglChooseConfig (self->egl_display, attrs, configs, alloced, &count))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Failed to get EGL configurations"));
|
||||
return FALSE;
|
||||
}
|
||||
g_warn_if_fail (alloced == count);
|
||||
|
||||
best_features = NO_VISUAL_FOUND;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
XVisualInfo *visinfo;
|
||||
int tmp, visualid;
|
||||
|
||||
if (!eglGetConfigAttrib (self->egl_display, configs[i], EGL_NATIVE_VISUAL_ID, &visualid))
|
||||
continue;
|
||||
|
||||
visinfo = gdk_x11_display_get_visual_info_for_visual (self, visualid);
|
||||
if (visinfo == NULL)
|
||||
continue;
|
||||
|
||||
if (!eglGetConfigAttrib (self->egl_display, configs[i], EGL_SAMPLE_BUFFERS, &tmp) || tmp != 0)
|
||||
{
|
||||
if (best_features < WITH_MULTISAMPLING)
|
||||
{
|
||||
GDK_NOTE (OPENGL, g_message ("Best EGL config is %u for visual 0x%lX with multisampling", i, visinfo->visualid));
|
||||
best_features = WITH_MULTISAMPLING;
|
||||
*out_visual = visinfo->visual;
|
||||
*out_depth = visinfo->depth;
|
||||
self->egl_config = configs[i];
|
||||
}
|
||||
XFree (visinfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib (self->egl_display, configs[i], EGL_DEPTH_SIZE, &tmp) || tmp != 0 ||
|
||||
!eglGetConfigAttrib (self->egl_display, configs[i], EGL_STENCIL_SIZE, &tmp) || tmp != 0)
|
||||
{
|
||||
GDK_NOTE (OPENGL, g_message ("Best EGL config is %u for visual 0x%lX with stencil or depth buffer", i, visinfo->visualid));
|
||||
if (best_features < WITH_STENCIL_AND_DEPTH_BUFFER)
|
||||
{
|
||||
best_features = WITH_STENCIL_AND_DEPTH_BUFFER;
|
||||
*out_visual = visinfo->visual;
|
||||
*out_depth = visinfo->depth;
|
||||
self->egl_config = configs[i];
|
||||
}
|
||||
XFree (visinfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!visual_is_rgba (visinfo))
|
||||
{
|
||||
GDK_NOTE (OPENGL, g_message ("Best EGL config is %u for visual 0x%lX without RGBA Visual", i, visinfo->visualid));
|
||||
if (best_features < NO_ALPHA_VISUAL)
|
||||
{
|
||||
best_features = NO_ALPHA_VISUAL;
|
||||
*out_visual = visinfo->visual;
|
||||
*out_depth = visinfo->depth;
|
||||
self->egl_config = configs[i];
|
||||
}
|
||||
XFree (visinfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
GDK_NOTE (OPENGL, g_message ("EGL Config %u for visual 0x%lX is the perfect choice", i, visinfo->visualid));
|
||||
*out_visual = visinfo->visual;
|
||||
*out_depth = visinfo->depth;
|
||||
self->egl_config = configs[i];
|
||||
XFree (visinfo);
|
||||
/* everything is perfect */
|
||||
best_features = PERFECT;
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (configs);
|
||||
|
||||
if (best_features == NO_VISUAL_FOUND)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No EGL configuration with required features found"));
|
||||
return FALSE;
|
||||
}
|
||||
else if (!force && best_features != PERFECT)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No perfect EGL configuration found"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef MAX_EGL_ATTRS
|
||||
|
||||
static EGLSurface
|
||||
gdk_x11_surface_get_egl_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkX11Surface *self = GDK_X11_SURFACE (surface);
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (self));
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (self->egl_surface)
|
||||
return self->egl_surface;
|
||||
|
||||
self->egl_surface =
|
||||
eglCreateWindowSurface (display_x11->egl_display,
|
||||
display_x11->egl_config,
|
||||
(EGLNativeWindowType) gdk_x11_surface_get_xid (surface),
|
||||
NULL);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (surface), "-gdk-x11-egl-drawable",
|
||||
info,
|
||||
drawable_info_free);
|
||||
return self->egl_surface;
|
||||
}
|
||||
|
||||
return info->egl_surface;
|
||||
void
|
||||
gdk_x11_surface_destroy_egl_surface (GdkX11Surface *self)
|
||||
{
|
||||
GdkX11Display *display_x11;
|
||||
|
||||
if (self->egl_surface == NULL)
|
||||
return;
|
||||
|
||||
display_x11 = GDK_X11_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self)));
|
||||
|
||||
eglDestroySurface (display_x11->egl_display, self->egl_surface);
|
||||
self->egl_surface = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->begin_frame (draw_context, region);
|
||||
|
||||
glDrawBuffers (1, (GLenum[1]) { GL_BACK });
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -277,20 +326,16 @@ gdk_x11_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkX11GLContextEGL *context_egl = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
EGLDisplay egl_display = gdk_x11_display_get_egl_display (display);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->end_frame (draw_context, painted);
|
||||
if (gdk_gl_context_get_shared_context (context) != NULL)
|
||||
return;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface, context_egl->egl_config);
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "x11", "swap buffers");
|
||||
if (display_x11->has_egl_swap_buffers_with_damage)
|
||||
@@ -319,11 +364,74 @@ gdk_x11_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
|
||||
eglSwapBuffersWithDamageEXT (egl_display, egl_surface, rects, n_rects);
|
||||
eglSwapBuffersWithDamageEXT (display_x11->egl_display, egl_surface, rects, n_rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
eglSwapBuffers (egl_display, egl_surface);
|
||||
eglSwapBuffers (display_x11->egl_display, egl_surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_egl_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
return eglMakeCurrent (display_x11->egl_display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkX11GLContextEGL *self = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
EGLSurface egl_surface;
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
if (surfaceless)
|
||||
{
|
||||
return eglMakeCurrent (display_x11->egl_display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
self->egl_context);
|
||||
}
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making EGL context %p current to surface %p",
|
||||
self->egl_context, egl_surface));
|
||||
|
||||
if (!eglMakeCurrent (display_x11->egl_display,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
self->egl_context))
|
||||
return FALSE;
|
||||
|
||||
/* If the WM 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 != self->do_frame_sync)
|
||||
{
|
||||
self->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
eglSwapInterval (display_x11->egl_display, 1);
|
||||
else
|
||||
eglSwapInterval (display_x11->egl_display, 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
@@ -335,20 +443,13 @@ gdk_x11_gl_context_egl_get_damage (GdkGLContext *context)
|
||||
if (display_x11->has_egl_buffer_age)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
GdkGLContext *shared = gdk_gl_context_get_shared_context (context);
|
||||
GdkX11GLContextEGL *shared_egl;
|
||||
EGLSurface egl_surface;
|
||||
int buffer_age = 0;
|
||||
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
if (shared == NULL)
|
||||
shared = context;
|
||||
shared_egl = GDK_X11_GL_CONTEXT_EGL (shared);
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface);
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface, shared_egl->egl_config);
|
||||
gdk_gl_context_make_current (shared);
|
||||
|
||||
eglQuerySurface (gdk_x11_display_get_egl_display (display),
|
||||
eglQuerySurface (display_x11->egl_display,
|
||||
egl_surface,
|
||||
EGL_BUFFER_AGE_EXT,
|
||||
&buffer_age);
|
||||
@@ -389,20 +490,16 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context,
|
||||
GdkX11Display *display_x11;
|
||||
GdkDisplay *display;
|
||||
GdkX11GLContextEGL *context_egl;
|
||||
GdkGLContext *share, *shared_data_context;
|
||||
GdkSurface *surface;
|
||||
GdkGLContext *share;
|
||||
gboolean debug_bit, forward_bit, legacy_bit, use_es;
|
||||
int major, minor, i = 0;
|
||||
EGLint context_attrs[N_EGL_ATTRS];
|
||||
EGLDisplay egl_display;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
display = gdk_surface_get_display (surface);
|
||||
display = gdk_gl_context_get_display (context);
|
||||
|
||||
context_egl = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
display_x11 = GDK_X11_DISPLAY (display);
|
||||
share = gdk_gl_context_get_shared_context (context);
|
||||
shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
|
||||
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);
|
||||
@@ -465,16 +562,12 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context,
|
||||
legacy_bit ? "yes" : "no",
|
||||
use_es ? "yes" : "no"));
|
||||
|
||||
egl_display = gdk_x11_display_get_egl_display (display);
|
||||
|
||||
context_egl->egl_context =
|
||||
eglCreateContext (egl_display,
|
||||
context_egl->egl_config,
|
||||
eglCreateContext (display_x11->egl_display,
|
||||
display_x11->egl_config,
|
||||
share != NULL
|
||||
? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
|
||||
: shared_data_context != NULL
|
||||
? GDK_X11_GL_CONTEXT_EGL (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attrs);
|
||||
|
||||
/* If we're not asking for a GLES context, and we don't have the legacy bit set
|
||||
@@ -493,13 +586,11 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context,
|
||||
g_message ("Context creation failed; trying legacy EGL context"));
|
||||
|
||||
context_egl->egl_context =
|
||||
eglCreateContext (egl_display,
|
||||
context_egl->egl_config,
|
||||
eglCreateContext (display_x11->egl_display,
|
||||
display_x11->egl_config,
|
||||
share != NULL
|
||||
? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
|
||||
: shared_data_context != NULL
|
||||
? GDK_X11_GL_CONTEXT_EGL (shared_data_context)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attrs);
|
||||
}
|
||||
|
||||
@@ -530,15 +621,14 @@ gdk_x11_gl_context_egl_dispose (GObject *gobject)
|
||||
if (context_egl->egl_context != NULL)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
EGLDisplay egl_display = gdk_x11_display_get_egl_display (display);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (gdk_gl_context_get_display (context));
|
||||
|
||||
/* Unset the current context if we're disposing it */
|
||||
if (eglGetCurrentContext () == context_egl->egl_context)
|
||||
eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglMakeCurrent (display_x11->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
GDK_NOTE (OPENGL, g_message ("Destroying EGL context"));
|
||||
eglDestroyContext (egl_display, context_egl->egl_context);
|
||||
eglDestroyContext (display_x11->egl_display, context_egl->egl_context);
|
||||
context_egl->egl_context = NULL;
|
||||
}
|
||||
|
||||
@@ -553,8 +643,11 @@ gdk_x11_gl_context_egl_class_init (GdkX11GLContextEGLClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
context_class->realize = gdk_x11_gl_context_egl_realize;
|
||||
context_class->make_current = gdk_x11_gl_context_egl_make_current;
|
||||
context_class->clear_current = gdk_x11_gl_context_egl_clear_current;
|
||||
context_class->get_damage = gdk_x11_gl_context_egl_get_damage;
|
||||
|
||||
draw_context_class->begin_frame = gdk_x11_gl_context_egl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_x11_gl_context_egl_end_frame;
|
||||
|
||||
gobject_class->dispose = gdk_x11_gl_context_egl_dispose;
|
||||
@@ -563,55 +656,84 @@ gdk_x11_gl_context_egl_class_init (GdkX11GLContextEGLClass *klass)
|
||||
static void
|
||||
gdk_x11_gl_context_egl_init (GdkX11GLContextEGL *self)
|
||||
{
|
||||
self->do_frame_sync = TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_screen_init_egl (GdkX11Screen *screen)
|
||||
gdk_x11_display_init_egl (GdkX11Display *self,
|
||||
gboolean force,
|
||||
Visual **out_visual,
|
||||
int *out_depth,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display = GDK_SCREEN_DISPLAY (screen);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
EGLDisplay edpy;
|
||||
GdkDisplay *display = GDK_DISPLAY (self);
|
||||
Display *dpy;
|
||||
int major, minor;
|
||||
|
||||
if (display_x11->have_egl)
|
||||
return TRUE;
|
||||
|
||||
dpy = gdk_x11_display_get_xdisplay (display);
|
||||
|
||||
if (!epoxy_has_egl ())
|
||||
return FALSE;
|
||||
|
||||
edpy = gdk_x11_display_get_egl_display (display);
|
||||
if (edpy == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!eglInitialize (edpy, &major, &minor))
|
||||
return FALSE;
|
||||
|
||||
/* While NVIDIA might support EGL, it might very well not support
|
||||
* all the EGL subset we rely on; we should be looking at more
|
||||
* EGL extensions, but for the time being, this is a blanket
|
||||
* fallback to GLX
|
||||
*/
|
||||
const char *vendor = eglQueryString (edpy, EGL_VENDOR);
|
||||
if (strstr (vendor, "NVIDIA") != NULL)
|
||||
{
|
||||
eglTerminate (edpy);
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("EGL is not supported"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display_x11->have_egl = TRUE;
|
||||
display_x11->egl_version = epoxy_egl_version (dpy);
|
||||
gdk_x11_display_create_egl_display (self);
|
||||
if (self->egl_display == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Failed to create EGL display"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display_x11->has_egl_khr_create_context =
|
||||
epoxy_has_egl_extension (edpy, "EGL_KHR_create_context");
|
||||
display_x11->has_egl_buffer_age =
|
||||
epoxy_has_egl_extension (edpy, "EGL_EXT_buffer_age");
|
||||
display_x11->has_egl_swap_buffers_with_damage =
|
||||
epoxy_has_egl_extension (edpy, "EGL_EXT_swap_buffers_with_damage");
|
||||
display_x11->has_egl_surfaceless_context =
|
||||
epoxy_has_egl_extension (edpy, "EGL_KHR_surfaceless_context");
|
||||
if (!eglInitialize (self->egl_display, &major, &minor))
|
||||
{
|
||||
self->egl_display = NULL;
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Could not initialize EGL display"));
|
||||
return FALSE;
|
||||
}
|
||||
if (major < GDK_EGL_MIN_VERSION_MAJOR ||
|
||||
(major == GDK_EGL_MIN_VERSION_MAJOR && minor < GDK_EGL_MIN_VERSION_MINOR))
|
||||
{
|
||||
eglTerminate (dpy);
|
||||
self->egl_display = NULL;
|
||||
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 FALSE;
|
||||
}
|
||||
|
||||
if (!epoxy_has_egl_extension (self->egl_display, "EGL_KHR_surfaceless_context"))
|
||||
{
|
||||
eglTerminate (dpy);
|
||||
self->egl_display = NULL;
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
|
||||
_("Surfaceless contexts are not supported on this EGL implementation"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gdk_x11_display_create_egl_config (self, force, out_visual, out_depth, error))
|
||||
{
|
||||
eglTerminate (self->egl_display);
|
||||
self->egl_display = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->egl_version = epoxy_egl_version (dpy);
|
||||
|
||||
self->has_egl_khr_create_context =
|
||||
epoxy_has_egl_extension (self->egl_display, "EGL_KHR_create_context");
|
||||
self->has_egl_buffer_age =
|
||||
epoxy_has_egl_extension (self->egl_display, "EGL_EXT_buffer_age");
|
||||
self->has_egl_swap_buffers_with_damage =
|
||||
epoxy_has_egl_extension (self->egl_display, "EGL_EXT_swap_buffers_with_damage");
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("EGL found\n"
|
||||
@@ -621,162 +743,13 @@ gdk_x11_screen_init_egl (GdkX11Screen *screen)
|
||||
" - Checked extensions:\n"
|
||||
"\t* EGL_KHR_create_context: %s\n"
|
||||
"\t* EGL_EXT_buffer_age: %s\n"
|
||||
"\t* EGL_EXT_swap_buffers_with_damage: %s\n"
|
||||
"\t* EGL_KHR_surfaceless_context: %s\n",
|
||||
eglQueryString (edpy, EGL_VERSION),
|
||||
eglQueryString (edpy, EGL_VENDOR),
|
||||
eglQueryString (edpy, EGL_CLIENT_APIS),
|
||||
display_x11->has_egl_khr_create_context ? "yes" : "no",
|
||||
display_x11->has_egl_buffer_age ? "yes" : "no",
|
||||
display_x11->has_egl_swap_buffers_with_damage ? "yes" : "no",
|
||||
display_x11->has_egl_surfaceless_context ? "yes" : "no"));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define MAX_EGL_ATTRS 30
|
||||
|
||||
static gboolean
|
||||
find_eglconfig_for_display (GdkDisplay *display,
|
||||
EGLConfig *egl_config_out,
|
||||
GError **error)
|
||||
{
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig egl_config;
|
||||
EGLDisplay egl_display;
|
||||
int i = 0;
|
||||
|
||||
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++] = 8;
|
||||
attrs[i++] = EGL_GREEN_SIZE;
|
||||
attrs[i++] = 8;
|
||||
attrs[i++] = EGL_BLUE_SIZE;
|
||||
attrs[i++] = 8;
|
||||
attrs[i++] = EGL_ALPHA_SIZE;
|
||||
attrs[i++] = 8;
|
||||
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
/* Pick first valid configuration that the driver returns us */
|
||||
egl_display = gdk_x11_display_get_egl_display (display);
|
||||
if (!eglChooseConfig (egl_display, attrs, &egl_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;
|
||||
}
|
||||
|
||||
g_assert (egl_config_out);
|
||||
*egl_config_out = egl_config;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef MAX_EGL_ATTRS
|
||||
|
||||
GdkX11GLContext *
|
||||
gdk_x11_gl_context_egl_new (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkX11GLContextEGL *context;
|
||||
EGLConfig egl_config;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
|
||||
if (!find_eglconfig_for_display (display, &egl_config, error))
|
||||
return NULL;
|
||||
|
||||
context = g_object_new (GDK_TYPE_X11_GL_CONTEXT_EGL,
|
||||
"surface", surface,
|
||||
"shared-context", share,
|
||||
NULL);
|
||||
|
||||
context->egl_config = egl_config;
|
||||
|
||||
return GDK_X11_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_gl_context_egl_make_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkX11GLContextEGL *context_egl = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
EGLDisplay egl_display;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
egl_display = gdk_x11_display_get_egl_display (display);
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (context_egl->egl_context == NULL)
|
||||
{
|
||||
g_critical ("No EGL context associated to the GdkGLContext; you must "
|
||||
"call gdk_gl_context_realize() first.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (context_x11->is_attached || gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)))
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface, context_egl->egl_config);
|
||||
else
|
||||
{
|
||||
if (display_x11->has_egl_surfaceless_context)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = gdk_x11_display_get_egl_dummy_surface (display, context_egl->egl_config);
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making EGL context %p current to surface %p",
|
||||
context_egl->egl_context, egl_surface));
|
||||
|
||||
if (!eglMakeCurrent (egl_display, egl_surface, egl_surface, context_egl->egl_context))
|
||||
{
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making EGL context current failed"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (context_x11->is_attached)
|
||||
{
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
/* If the WM 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_x11->do_frame_sync)
|
||||
{
|
||||
context_x11->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
eglSwapInterval (egl_display, 1);
|
||||
else
|
||||
eglSwapInterval (egl_display, 0);
|
||||
}
|
||||
}
|
||||
"\t* EGL_EXT_swap_buffers_with_damage: %s\n",
|
||||
eglQueryString (self->egl_display, EGL_VERSION),
|
||||
eglQueryString (self->egl_display, EGL_VENDOR),
|
||||
eglQueryString (self->egl_display, EGL_CLIENT_APIS),
|
||||
self->has_egl_khr_create_context ? "yes" : "no",
|
||||
self->has_egl_buffer_age ? "yes" : "no",
|
||||
self->has_egl_swap_buffers_with_damage ? "yes" : "no"));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -805,10 +778,7 @@ gdk_x11_display_get_egl_version (GdkDisplay *display,
|
||||
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (display_x11->have_glx)
|
||||
return FALSE;
|
||||
|
||||
if (!gdk_x11_screen_init_egl (display_x11->screen))
|
||||
if (display_x11->egl_display == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (major != NULL)
|
||||
|
||||
+228
-556
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@
|
||||
#include "gdkx11glcontext.h"
|
||||
#include "gdkx11screen.h"
|
||||
#include "gdkx11surface.h"
|
||||
#include "gdkvisual-x11.h"
|
||||
#include "gdkx11property.h"
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
@@ -51,78 +50,5 @@ gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
|
||||
static void
|
||||
gdk_x11_gl_context_init (GdkX11GLContext *self)
|
||||
{
|
||||
self->do_frame_sync = TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_screen_init_gl (GdkX11Screen *screen)
|
||||
{
|
||||
GdkDisplay *display G_GNUC_UNUSED = GDK_SCREEN_DISPLAY (screen);
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_DISABLE))
|
||||
return FALSE;
|
||||
|
||||
if (!GDK_DISPLAY_DEBUG_CHECK (display, GL_GLX))
|
||||
{
|
||||
/* We favour EGL */
|
||||
if (gdk_x11_screen_init_egl (screen))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (gdk_x11_screen_init_glx (screen))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_x11_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkX11GLContext *context = NULL;
|
||||
GdkX11Display *display_x11;
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
|
||||
if (!gdk_x11_screen_init_gl (GDK_SURFACE_SCREEN (surface)))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("No GL implementation is available"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
display_x11 = GDK_X11_DISPLAY (display);
|
||||
if (display_x11->have_egl)
|
||||
context = gdk_x11_gl_context_egl_new (surface, attached, share, error);
|
||||
else if (display_x11->have_glx)
|
||||
context = gdk_x11_gl_context_glx_new (surface, attached, share, error);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
if (context == NULL)
|
||||
return NULL;
|
||||
|
||||
context->is_attached = attached;
|
||||
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (display_x11->have_egl)
|
||||
return gdk_x11_gl_context_egl_make_current (display, context);
|
||||
else if (display_x11->have_glx)
|
||||
return gdk_x11_gl_context_glx_make_current (display, context);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+13
-31
@@ -34,8 +34,7 @@
|
||||
#include <epoxy/glx.h>
|
||||
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkvisual-x11.h"
|
||||
#include "gdkdisplay-x11.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
@@ -48,27 +47,13 @@ G_BEGIN_DECLS
|
||||
struct _GdkX11GLContext
|
||||
{
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
guint do_frame_sync : 1;
|
||||
guint is_attached : 1;
|
||||
};
|
||||
|
||||
struct _GdkX11GLContextClass
|
||||
{
|
||||
GdkGLContextClass parent_class;
|
||||
|
||||
void (* bind_for_frame_fence) (GdkX11GLContext *self);
|
||||
};
|
||||
|
||||
gboolean gdk_x11_screen_init_gl (GdkX11Screen *screen);
|
||||
|
||||
GdkGLContext * gdk_x11_surface_create_gl_context (GdkSurface *window,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gboolean gdk_x11_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
/* GLX */
|
||||
#define GDK_TYPE_X11_GL_CONTEXT_GLX (gdk_x11_gl_context_glx_get_type())
|
||||
#define GDK_X11_GL_CONTEXT_GLX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_X11_GL_CONTEXT_GLX, GdkX11GLContextGLX))
|
||||
@@ -76,16 +61,13 @@ gboolean gdk_x11_display_make_gl_context_current (GdkDisplay *display,
|
||||
|
||||
typedef struct _GdkX11GLContextGLX GdkX11GLContextGLX;
|
||||
|
||||
gboolean gdk_x11_screen_init_glx (GdkX11Screen *screen);
|
||||
void gdk_x11_screen_update_visuals_for_glx (GdkX11Screen *screen);
|
||||
gboolean gdk_x11_display_init_glx (GdkX11Display *display_x11,
|
||||
Visual **out_visual,
|
||||
int *out_depth,
|
||||
GError **error);
|
||||
void gdk_x11_surface_destroy_glx_drawable (GdkX11Surface *self);
|
||||
|
||||
GType gdk_x11_gl_context_glx_get_type (void) G_GNUC_CONST;
|
||||
GdkX11GLContext * gdk_x11_gl_context_glx_new (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gboolean gdk_x11_gl_context_glx_make_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
|
||||
/* EGL */
|
||||
@@ -95,14 +77,14 @@ gboolean gdk_x11_gl_context_glx_make_current (GdkDisplay *
|
||||
|
||||
typedef struct _GdkX11GLContextEGL GdkX11GLContextEGL;
|
||||
|
||||
gboolean gdk_x11_screen_init_egl (GdkX11Screen *screen);
|
||||
GType gdk_x11_gl_context_egl_get_type (void) G_GNUC_CONST;
|
||||
GdkX11GLContext * gdk_x11_gl_context_egl_new (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
gboolean gdk_x11_display_init_egl (GdkX11Display *display_x11,
|
||||
gboolean force,
|
||||
Visual **out_visual,
|
||||
int *out_depth,
|
||||
GError **error);
|
||||
gboolean gdk_x11_gl_context_egl_make_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
void gdk_x11_surface_destroy_egl_surface (GdkX11Surface *self);
|
||||
|
||||
GType gdk_x11_gl_context_egl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -55,11 +55,6 @@ typedef GdkFilterReturn (*GdkFilterFunc) (const XEvent *xevent,
|
||||
void _gdk_x11_error_handler_push (void);
|
||||
void _gdk_x11_error_handler_pop (void);
|
||||
|
||||
void gdk_display_setup_window_visual (GdkDisplay *display,
|
||||
int depth,
|
||||
Visual *visual,
|
||||
Colormap colormap,
|
||||
gboolean rgba);
|
||||
int gdk_x11_display_get_window_depth (GdkX11Display *display);
|
||||
Visual * gdk_x11_display_get_window_visual (GdkX11Display *display);
|
||||
Colormap gdk_x11_display_get_window_colormap (GdkX11Display *display);
|
||||
|
||||
+1
-13
@@ -91,9 +91,6 @@ gdk_x11_screen_dispose (GObject *object)
|
||||
|
||||
_gdk_x11_xsettings_finish (x11_screen);
|
||||
|
||||
for (i = 0; i < x11_screen->nvisuals; i++)
|
||||
g_object_run_dispose (G_OBJECT (x11_screen->visuals[i]));
|
||||
|
||||
G_OBJECT_CLASS (gdk_x11_screen_parent_class)->dispose (object);
|
||||
|
||||
x11_screen->xdisplay = NULL;
|
||||
@@ -106,12 +103,6 @@ static void
|
||||
gdk_x11_screen_finalize (GObject *object)
|
||||
{
|
||||
GdkX11Screen *x11_screen = GDK_X11_SCREEN (object);
|
||||
int i;
|
||||
|
||||
/* Visual Part */
|
||||
for (i = 0; i < x11_screen->nvisuals; i++)
|
||||
g_object_unref (x11_screen->visuals[i]);
|
||||
g_free (x11_screen->visuals);
|
||||
|
||||
g_free (x11_screen->window_manager_name);
|
||||
|
||||
@@ -866,8 +857,7 @@ init_multihead (GdkX11Screen *screen)
|
||||
|
||||
GdkX11Screen *
|
||||
_gdk_x11_screen_new (GdkDisplay *display,
|
||||
int screen_number,
|
||||
gboolean setup_display)
|
||||
int screen_number)
|
||||
{
|
||||
GdkX11Screen *x11_screen;
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
@@ -898,8 +888,6 @@ _gdk_x11_screen_new (GdkDisplay *display,
|
||||
init_randr_support (x11_screen);
|
||||
init_multihead (x11_screen);
|
||||
|
||||
_gdk_x11_screen_init_visuals (x11_screen, setup_display);
|
||||
|
||||
return x11_screen;
|
||||
}
|
||||
|
||||
|
||||
+1
-16
@@ -23,7 +23,6 @@
|
||||
#define __GDK_X11_SCREEN__
|
||||
|
||||
#include "gdkx11screen.h"
|
||||
#include "gdkvisual-x11.h"
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
@@ -71,16 +70,6 @@ struct _GdkX11Screen
|
||||
guint xft_antialias : 1;
|
||||
guint xft_hinting : 1;
|
||||
|
||||
/* Visual Part */
|
||||
int nvisuals;
|
||||
GdkX11Visual **visuals;
|
||||
GdkX11Visual *system_visual;
|
||||
int available_depths[7];
|
||||
GdkVisualType available_types[6];
|
||||
gint16 navailable_depths;
|
||||
gint16 navailable_types;
|
||||
GdkX11Visual *rgba_visual;
|
||||
|
||||
/* cache for window->translate vfunc */
|
||||
GC subwindow_gcs[32];
|
||||
};
|
||||
@@ -94,8 +83,7 @@ struct _GdkX11ScreenClass
|
||||
|
||||
GType _gdk_x11_screen_get_type (void);
|
||||
GdkX11Screen *_gdk_x11_screen_new (GdkDisplay *display,
|
||||
int screen_number,
|
||||
gboolean setup_display);
|
||||
int screen_number);
|
||||
|
||||
void _gdk_x11_screen_window_manager_changed (GdkX11Screen *screen);
|
||||
void _gdk_x11_screen_size_changed (GdkX11Screen *screen,
|
||||
@@ -120,9 +108,6 @@ _gdk_x11_screen_get_xft_setting (GdkX11Screen *screen,
|
||||
const char *name,
|
||||
GValue *value);
|
||||
|
||||
void _gdk_x11_screen_init_visuals (GdkX11Screen *screen,
|
||||
gboolean setup_display);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_X11_SCREEN__ */
|
||||
|
||||
+12
-30
@@ -31,7 +31,6 @@
|
||||
#include "gdkpopupprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkdragsurfaceprivate.h"
|
||||
#include "gdkvisual-x11.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevice-xi2-private.h"
|
||||
@@ -65,14 +64,6 @@
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XCOMPOSITE
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XFIXES
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#endif
|
||||
|
||||
const int _gdk_x11_event_mask_table[21] =
|
||||
{
|
||||
ExposureMask,
|
||||
@@ -1169,16 +1160,12 @@ _gdk_x11_display_create_surface (GdkDisplay *display,
|
||||
GdkX11Display *display_x11;
|
||||
|
||||
Window xparent;
|
||||
Visual *xvisual;
|
||||
Display *xdisplay;
|
||||
|
||||
XSetWindowAttributes xattributes;
|
||||
long xattributes_mask;
|
||||
XClassHint *class_hint;
|
||||
|
||||
unsigned int class;
|
||||
int depth;
|
||||
|
||||
int abs_x;
|
||||
int abs_y;
|
||||
|
||||
@@ -1231,12 +1218,8 @@ _gdk_x11_display_create_surface (GdkDisplay *display,
|
||||
|
||||
xattributes_mask = 0;
|
||||
|
||||
xvisual = gdk_x11_display_get_window_visual (display_x11);
|
||||
|
||||
impl->override_redirect = FALSE;
|
||||
|
||||
class = InputOutput;
|
||||
|
||||
xattributes.background_pixmap = None;
|
||||
xattributes_mask |= CWBackPixmap;
|
||||
|
||||
@@ -1260,8 +1243,6 @@ _gdk_x11_display_create_surface (GdkDisplay *display,
|
||||
impl->override_redirect = TRUE;
|
||||
}
|
||||
|
||||
depth = gdk_x11_display_get_window_depth (display_x11);
|
||||
|
||||
if (surface->width * impl->surface_scale > 32767 ||
|
||||
surface->height * impl->surface_scale > 32767)
|
||||
{
|
||||
@@ -1284,7 +1265,10 @@ _gdk_x11_display_create_surface (GdkDisplay *display,
|
||||
(surface->y + abs_y) * impl->surface_scale,
|
||||
MAX (1, surface->width * impl->surface_scale),
|
||||
MAX (1, surface->height * impl->surface_scale),
|
||||
0, depth, class, xvisual,
|
||||
0,
|
||||
gdk_x11_display_get_window_depth (display_x11),
|
||||
InputOutput,
|
||||
gdk_x11_display_get_window_visual (display_x11),
|
||||
xattributes_mask, &xattributes);
|
||||
|
||||
g_object_ref (surface);
|
||||
@@ -1375,7 +1359,12 @@ gdk_x11_surface_destroy (GdkSurface *surface,
|
||||
}
|
||||
|
||||
if (!foreign_destroy)
|
||||
XDestroyWindow (GDK_SURFACE_XDISPLAY (surface), GDK_SURFACE_XID (surface));
|
||||
{
|
||||
gdk_x11_surface_destroy_egl_surface (impl);
|
||||
gdk_x11_surface_destroy_glx_drawable (impl);
|
||||
|
||||
XDestroyWindow (GDK_SURFACE_XDISPLAY (surface), GDK_SURFACE_XID (surface));
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called when the XWindow is really gone.
|
||||
@@ -1644,6 +1633,8 @@ gdk_x11_surface_hide (GdkSurface *surface)
|
||||
g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
|
||||
|
||||
gdk_x11_surface_withdraw (surface);
|
||||
|
||||
impl->glx_frame_counter = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -2445,14 +2436,6 @@ gdk_x11_surface_set_geometry_hints (GdkSurface *surface,
|
||||
}
|
||||
|
||||
size_hints.flags = 0;
|
||||
|
||||
size_hints.flags |= PPosition;
|
||||
/* We need to initialize the following obsolete fields because KWM
|
||||
* apparently uses these fields if they are non-zero.
|
||||
* #@#!#!$!.
|
||||
*/
|
||||
size_hints.x = 0;
|
||||
size_hints.y = 0;
|
||||
|
||||
if (geom_mask & GDK_HINT_MIN_SIZE)
|
||||
{
|
||||
@@ -4821,7 +4804,6 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
|
||||
impl_class->drag_begin = _gdk_x11_surface_drag_begin;
|
||||
impl_class->get_scale_factor = gdk_x11_surface_get_scale_factor;
|
||||
impl_class->set_opaque_region = gdk_x11_surface_set_opaque_region;
|
||||
impl_class->create_gl_context = gdk_x11_surface_create_gl_context;
|
||||
impl_class->request_layout = gdk_x11_surface_request_layout;
|
||||
impl_class->compute_size = gdk_x11_surface_compute_size;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,9 @@ struct _GdkX11Surface
|
||||
guint compute_size_source_id;
|
||||
|
||||
cairo_surface_t *cairo_surface;
|
||||
/* EGLSurface */ gpointer egl_surface;
|
||||
/* GLXDrawable */ XID glx_drawable;
|
||||
guint32 glx_frame_counter;
|
||||
|
||||
int abs_x;
|
||||
int abs_y;
|
||||
|
||||
@@ -1,322 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkscreen-x11.h"
|
||||
#include "gdkvisual-x11.h"
|
||||
#include "gdkglcontext-x11.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
struct _GdkX11VisualClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkX11Visual, gdk_x11_visual, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_x11_visual_init (GdkX11Visual *x11_visual)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_visual_class_init (GdkX11VisualClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_x11_screen_init_visuals (GdkX11Screen *x11_screen,
|
||||
gboolean setup_display)
|
||||
{
|
||||
static const int possible_depths[8] = { 32, 30, 24, 16, 15, 8, 4, 1 };
|
||||
static const GdkVisualType possible_types[6] =
|
||||
{
|
||||
GDK_VISUAL_DIRECT_COLOR,
|
||||
GDK_VISUAL_TRUE_COLOR,
|
||||
GDK_VISUAL_PSEUDO_COLOR,
|
||||
GDK_VISUAL_STATIC_COLOR,
|
||||
GDK_VISUAL_GRAYSCALE,
|
||||
GDK_VISUAL_STATIC_GRAY
|
||||
};
|
||||
|
||||
XVisualInfo *visual_list;
|
||||
XVisualInfo visual_template;
|
||||
GdkX11Visual *temp_visual;
|
||||
Visual *default_xvisual;
|
||||
GdkX11Visual **visuals;
|
||||
int nxvisuals;
|
||||
int nvisuals;
|
||||
int i, j;
|
||||
|
||||
nxvisuals = 0;
|
||||
visual_template.screen = x11_screen->screen_num;
|
||||
visual_list = XGetVisualInfo (x11_screen->xdisplay, VisualScreenMask, &visual_template, &nxvisuals);
|
||||
|
||||
visuals = g_new (GdkX11Visual *, nxvisuals);
|
||||
for (i = 0; i < nxvisuals; i++)
|
||||
visuals[i] = g_object_new (GDK_TYPE_X11_VISUAL, NULL);
|
||||
|
||||
default_xvisual = DefaultVisual (x11_screen->xdisplay, x11_screen->screen_num);
|
||||
|
||||
nvisuals = 0;
|
||||
for (i = 0; i < nxvisuals; i++)
|
||||
{
|
||||
if (visual_list[i].depth >= 1)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
switch (visual_list[i].c_class)
|
||||
#else /* __cplusplus */
|
||||
switch (visual_list[i].class)
|
||||
#endif /* __cplusplus */
|
||||
{
|
||||
case StaticGray:
|
||||
visuals[nvisuals]->type = GDK_VISUAL_STATIC_GRAY;
|
||||
break;
|
||||
case GrayScale:
|
||||
visuals[nvisuals]->type = GDK_VISUAL_GRAYSCALE;
|
||||
break;
|
||||
case StaticColor:
|
||||
visuals[nvisuals]->type = GDK_VISUAL_STATIC_COLOR;
|
||||
break;
|
||||
case PseudoColor:
|
||||
visuals[nvisuals]->type = GDK_VISUAL_PSEUDO_COLOR;
|
||||
break;
|
||||
case TrueColor:
|
||||
visuals[nvisuals]->type = GDK_VISUAL_TRUE_COLOR;
|
||||
break;
|
||||
case DirectColor:
|
||||
visuals[nvisuals]->type = GDK_VISUAL_DIRECT_COLOR;
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
visuals[nvisuals]->depth = visual_list[i].depth;
|
||||
visuals[nvisuals]->byte_order =
|
||||
(ImageByteOrder(x11_screen->xdisplay) == LSBFirst) ?
|
||||
GDK_LSB_FIRST : GDK_MSB_FIRST;
|
||||
visuals[nvisuals]->red_mask = visual_list[i].red_mask;
|
||||
visuals[nvisuals]->green_mask = visual_list[i].green_mask;
|
||||
visuals[nvisuals]->blue_mask = visual_list[i].blue_mask;
|
||||
visuals[nvisuals]->colormap_size = visual_list[i].colormap_size;
|
||||
visuals[nvisuals]->bits_per_rgb = visual_list[i].bits_per_rgb;
|
||||
GDK_X11_VISUAL (visuals[nvisuals])->xvisual = visual_list[i].visual;
|
||||
|
||||
if ((visuals[nvisuals]->type != GDK_VISUAL_TRUE_COLOR) &&
|
||||
(visuals[nvisuals]->type != GDK_VISUAL_DIRECT_COLOR))
|
||||
{
|
||||
visuals[nvisuals]->red_mask = 0;
|
||||
visuals[nvisuals]->green_mask = 0;
|
||||
visuals[nvisuals]->blue_mask = 0;
|
||||
}
|
||||
|
||||
nvisuals += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (visual_list)
|
||||
XFree (visual_list);
|
||||
|
||||
for (i = 0; i < nvisuals; i++)
|
||||
{
|
||||
for (j = i+1; j < nvisuals; j++)
|
||||
{
|
||||
if (visuals[j]->depth >= visuals[i]->depth)
|
||||
{
|
||||
if ((visuals[j]->depth == 8) && (visuals[i]->depth == 8))
|
||||
{
|
||||
if (visuals[j]->type == GDK_VISUAL_PSEUDO_COLOR)
|
||||
{
|
||||
temp_visual = visuals[j];
|
||||
visuals[j] = visuals[i];
|
||||
visuals[i] = temp_visual;
|
||||
}
|
||||
else if ((visuals[i]->type != GDK_VISUAL_PSEUDO_COLOR) &&
|
||||
visuals[j]->type > visuals[i]->type)
|
||||
{
|
||||
temp_visual = visuals[j];
|
||||
visuals[j] = visuals[i];
|
||||
visuals[i] = temp_visual;
|
||||
}
|
||||
}
|
||||
else if ((visuals[j]->depth > visuals[i]->depth) ||
|
||||
((visuals[j]->depth == visuals[i]->depth) &&
|
||||
(visuals[j]->type > visuals[i]->type)))
|
||||
{
|
||||
temp_visual = visuals[j];
|
||||
visuals[j] = visuals[i];
|
||||
visuals[i] = temp_visual;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nvisuals; i++)
|
||||
{
|
||||
if (default_xvisual->visualid == GDK_X11_VISUAL (visuals[i])->xvisual->visualid)
|
||||
x11_screen->system_visual = visuals[i];
|
||||
|
||||
/* For now, we only support 8888 ARGB for the "rgba visual".
|
||||
* Additional formats (like ABGR) could be added later if they
|
||||
* turn up.
|
||||
*/
|
||||
if (x11_screen->rgba_visual == NULL &&
|
||||
visuals[i]->depth == 32 &&
|
||||
(visuals[i]->red_mask == 0xff0000 &&
|
||||
visuals[i]->green_mask == 0x00ff00 &&
|
||||
visuals[i]->blue_mask == 0x0000ff))
|
||||
{
|
||||
x11_screen->rgba_visual = visuals[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (GDK_SCREEN_DISPLAY (x11_screen), MISC))
|
||||
{
|
||||
static const char *const visual_names[] =
|
||||
{
|
||||
"static gray",
|
||||
"grayscale",
|
||||
"static color",
|
||||
"pseudo color",
|
||||
"true color",
|
||||
"direct color",
|
||||
};
|
||||
|
||||
for (i = 0; i < nvisuals; i++)
|
||||
g_message ("visual: %s: %d", visual_names[visuals[i]->type], visuals[i]->depth);
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
x11_screen->navailable_depths = 0;
|
||||
for (i = 0; i < G_N_ELEMENTS (possible_depths); i++)
|
||||
{
|
||||
for (j = 0; j < nvisuals; j++)
|
||||
{
|
||||
if (visuals[j]->depth == possible_depths[i])
|
||||
{
|
||||
x11_screen->available_depths[x11_screen->navailable_depths++] = visuals[j]->depth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x11_screen->navailable_depths == 0)
|
||||
g_error ("unable to find a usable depth");
|
||||
|
||||
x11_screen->navailable_types = 0;
|
||||
for (i = 0; i < G_N_ELEMENTS (possible_types); i++)
|
||||
{
|
||||
for (j = 0; j < nvisuals; j++)
|
||||
{
|
||||
if (visuals[j]->type == possible_types[i])
|
||||
{
|
||||
x11_screen->available_types[x11_screen->navailable_types++] = visuals[j]->type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x11_screen->navailable_types == 0)
|
||||
g_error ("unable to find a usable visual type");
|
||||
|
||||
x11_screen->visuals = visuals;
|
||||
x11_screen->nvisuals = nvisuals;
|
||||
|
||||
/* If GL is available we want to pick better default/rgba visuals,
|
||||
* as we care about GLX details such as alpha/depth/stencil depth,
|
||||
* stereo and double buffering
|
||||
*/
|
||||
gdk_x11_screen_update_visuals_for_glx (x11_screen);
|
||||
|
||||
if (setup_display)
|
||||
{
|
||||
if (x11_screen->rgba_visual)
|
||||
{
|
||||
Visual *xvisual = GDK_X11_VISUAL (x11_screen->rgba_visual)->xvisual;
|
||||
Colormap colormap;
|
||||
|
||||
colormap = XCreateColormap (x11_screen->xdisplay,
|
||||
RootWindow (x11_screen->xdisplay, x11_screen->screen_num),
|
||||
xvisual,
|
||||
AllocNone);
|
||||
gdk_display_setup_window_visual (GDK_SCREEN_DISPLAY (x11_screen),
|
||||
x11_screen->rgba_visual->depth,
|
||||
GDK_X11_VISUAL (x11_screen->rgba_visual)->xvisual,
|
||||
colormap,
|
||||
TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_display_setup_window_visual (GDK_SCREEN_DISPLAY (x11_screen),
|
||||
DefaultDepth (x11_screen->xdisplay, x11_screen->screen_num),
|
||||
DefaultVisual (x11_screen->xdisplay, x11_screen->screen_num),
|
||||
DefaultColormap (x11_screen->xdisplay, x11_screen->screen_num),
|
||||
FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_x11_screen_lookup_visual:
|
||||
* @screen: a `GdkX11Screen`
|
||||
* @xvisualid: an X Visual ID.
|
||||
*
|
||||
* Looks up the `GdkVisual` for a particular screen and X Visual ID.
|
||||
*
|
||||
* Returns: (transfer none) (nullable) (type GdkX11Visual): the `GdkVisual`
|
||||
*/
|
||||
GdkX11Visual *
|
||||
gdk_x11_screen_lookup_visual (GdkX11Screen *x11_screen,
|
||||
VisualID xvisualid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < x11_screen->nvisuals; i++)
|
||||
if (xvisualid == GDK_X11_VISUAL (x11_screen->visuals[i])->xvisual->visualid)
|
||||
return x11_screen->visuals[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_x11_visual_get_xvisual:
|
||||
* @visual: a `GdkX11Visual`
|
||||
*
|
||||
* Returns the X visual belonging to a `GdkX11Visual`.
|
||||
*
|
||||
* Returns: (transfer none): an Xlib Visual*.
|
||||
**/
|
||||
Visual *
|
||||
gdk_x11_visual_get_xvisual (GdkX11Visual *visual)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_X11_VISUAL (visual), NULL);
|
||||
|
||||
return GDK_X11_VISUAL (visual)->xvisual;
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_X11_VISUAL__
|
||||
#define __GDK_X11_VISUAL__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/x11/gdkx11screen.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_X11_VISUAL (gdk_x11_visual_get_type ())
|
||||
#define GDK_X11_VISUAL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_X11_VISUAL, GdkX11Visual))
|
||||
#define GDK_X11_VISUAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_X11_VISUAL, GdkX11VisualClass))
|
||||
#define GDK_IS_X11_VISUAL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_X11_VISUAL))
|
||||
#define GDK_IS_X11_VISUAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_X11_VISUAL))
|
||||
#define GDK_X11_VISUAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_X11_VISUAL, GdkX11VisualClass))
|
||||
|
||||
typedef struct _GdkX11Visual GdkX11Visual;
|
||||
typedef struct _GdkX11VisualClass GdkX11VisualClass;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_VISUAL_STATIC_GRAY,
|
||||
GDK_VISUAL_GRAYSCALE,
|
||||
GDK_VISUAL_STATIC_COLOR,
|
||||
GDK_VISUAL_PSEUDO_COLOR,
|
||||
GDK_VISUAL_TRUE_COLOR,
|
||||
GDK_VISUAL_DIRECT_COLOR
|
||||
} GdkVisualType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_LSB_FIRST,
|
||||
GDK_MSB_FIRST
|
||||
} GdkByteOrder;
|
||||
|
||||
struct _GdkX11Visual
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkVisualType type;
|
||||
int depth;
|
||||
GdkByteOrder byte_order;
|
||||
int colormap_size;
|
||||
int bits_per_rgb;
|
||||
|
||||
guint32 red_mask;
|
||||
guint32 green_mask;
|
||||
guint32 blue_mask;
|
||||
|
||||
Visual *xvisual;
|
||||
};
|
||||
|
||||
GType gdk_x11_visual_get_type (void);
|
||||
|
||||
Visual * gdk_x11_visual_get_xvisual (GdkX11Visual *visual);
|
||||
|
||||
#define GDK_VISUAL_XVISUAL(visual) (gdk_x11_visual_get_xvisual (visual))
|
||||
|
||||
GdkX11Visual* gdk_x11_screen_lookup_visual (GdkX11Screen *screen,
|
||||
VisualID xvisualid);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,6 @@ gdk_x11_public_sources = files([
|
||||
'gdkproperty-x11.c',
|
||||
'gdkscreen-x11.c',
|
||||
'gdkselection-x11.c',
|
||||
'gdkvisual-x11.c',
|
||||
'gdksurface-x11.c',
|
||||
'gdkxid.c',
|
||||
'xsettings-client.c',
|
||||
@@ -69,7 +68,6 @@ gdk_x11_deps = [
|
||||
xcursor_dep,
|
||||
xdamage_dep,
|
||||
xfixes_dep,
|
||||
xcomposite_dep,
|
||||
xrandr_dep,
|
||||
xinerama_dep,
|
||||
]
|
||||
|
||||
@@ -518,14 +518,13 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture))
|
||||
{
|
||||
GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture);
|
||||
GdkGLContext *shared_context = gdk_gl_context_get_shared_context (self->gl_context);
|
||||
GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
|
||||
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
|
||||
|
||||
if (texture_context == self->gl_context ||
|
||||
(gdk_gl_context_get_shared_context (texture_context) == shared_context && shared_context != NULL))
|
||||
if (gdk_gl_context_is_shared (self->gl_context, texture_context))
|
||||
{
|
||||
/* A GL texture from the same GL context is a simple task... */
|
||||
return gdk_gl_texture_get_id ((GdkGLTexture *)texture);
|
||||
return gdk_gl_texture_get_id (gl_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2780,6 +2780,17 @@ gsk_container_node_get_child (const GskRenderNode *node,
|
||||
return self->children[idx];
|
||||
}
|
||||
|
||||
GskRenderNode **
|
||||
gsk_container_node_get_children (const GskRenderNode *node,
|
||||
guint *n_children)
|
||||
{
|
||||
const GskContainerNode *self = (const GskContainerNode *) node;
|
||||
|
||||
*n_children = self->n_children;
|
||||
|
||||
return self->children;
|
||||
}
|
||||
|
||||
/*** GSK_TRANSFORM_NODE ***/
|
||||
|
||||
/**
|
||||
@@ -2793,6 +2804,7 @@ struct _GskTransformNode
|
||||
|
||||
GskRenderNode *child;
|
||||
GskTransform *transform;
|
||||
float dx, dy;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -2944,6 +2956,11 @@ gsk_transform_node_new (GskRenderNode *child,
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->transform = gsk_transform_ref (transform);
|
||||
|
||||
if (gsk_transform_get_category (transform) >= GSK_TRANSFORM_CATEGORY_2D_TRANSLATE)
|
||||
gsk_transform_to_translate (transform, &self->dx, &self->dy);
|
||||
else
|
||||
self->dx = self->dy = 0;
|
||||
|
||||
gsk_transform_transform_bounds (self->transform,
|
||||
&child->bounds,
|
||||
&node->bounds);
|
||||
@@ -2983,6 +3000,17 @@ gsk_transform_node_get_transform (const GskRenderNode *node)
|
||||
return self->transform;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_transform_node_get_translate (const GskRenderNode *node,
|
||||
float *dx,
|
||||
float *dy)
|
||||
{
|
||||
const GskTransformNode *self = (const GskTransformNode *) node;
|
||||
|
||||
*dx = self->dx;
|
||||
*dy = self->dy;
|
||||
}
|
||||
|
||||
/*** GSK_OPACITY_NODE ***/
|
||||
|
||||
/**
|
||||
|
||||
@@ -2352,18 +2352,6 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (glyphs[i].glyph == ascii->glyphs[j].glyph)
|
||||
{
|
||||
if (glyphs[i].geometry.width != ascii->glyphs[j].geometry.width)
|
||||
g_print ("not ascii because of width (%d != %d)\n",
|
||||
glyphs[i].geometry.width,
|
||||
ascii->glyphs[j].geometry.width);
|
||||
if (glyphs[i].geometry.x_offset != 0 ||
|
||||
glyphs[i].geometry.y_offset != 0)
|
||||
g_print ("not ascii because of offset\n");
|
||||
if (!glyphs[i].attr.is_cluster_start)
|
||||
g_print ("not ascii because of cluster\n");
|
||||
}
|
||||
}
|
||||
if (j != ascii->num_glyphs)
|
||||
continue;
|
||||
@@ -2375,16 +2363,16 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
|
||||
g_string_set_size (str, 0);
|
||||
}
|
||||
|
||||
g_string_append_printf (p, "%u %g",
|
||||
glyphs[i].glyph,
|
||||
(double) glyphs[i].geometry.width / PANGO_SCALE);
|
||||
g_string_append_printf (p, "%u ", glyphs[i].glyph);
|
||||
string_append_double (p, (double) glyphs[i].geometry.width / PANGO_SCALE);
|
||||
if (!glyphs[i].attr.is_cluster_start ||
|
||||
glyphs[i].geometry.x_offset != 0 ||
|
||||
glyphs[i].geometry.y_offset != 0)
|
||||
{
|
||||
g_string_append_printf (p, " %g %g",
|
||||
(double) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
(double) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
g_string_append (p, " ");
|
||||
string_append_double (p, (double) glyphs[i].geometry.x_offset / PANGO_SCALE);
|
||||
g_string_append (p, " ");
|
||||
string_append_double (p, (double) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
if (!glyphs[i].attr.is_cluster_start)
|
||||
g_string_append (p, " same-cluster");
|
||||
}
|
||||
|
||||
@@ -103,6 +103,14 @@ bool gsk_border_node_get_uniform_color (const GskRenderNode
|
||||
void gsk_text_node_serialize_glyphs (GskRenderNode *self,
|
||||
GString *str);
|
||||
|
||||
GskRenderNode ** gsk_container_node_get_children (const GskRenderNode *node,
|
||||
guint *n_children);
|
||||
|
||||
void gsk_transform_node_get_translate (const GskRenderNode *node,
|
||||
float *dx,
|
||||
float *dy);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_RENDER_NODE_PRIVATE_H__ */
|
||||
|
||||
+29
-58
@@ -1487,21 +1487,21 @@ gsk_transform_to_2d (GskTransform *self,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
if (self == NULL ||
|
||||
self->category < GSK_TRANSFORM_CATEGORY_2D)
|
||||
*out_xx = 1.0f;
|
||||
*out_yx = 0.0f;
|
||||
*out_xy = 0.0f;
|
||||
*out_yy = 1.0f;
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
|
||||
if (self == NULL)
|
||||
return;
|
||||
|
||||
if (G_UNLIKELY (self->category < GSK_TRANSFORM_CATEGORY_2D))
|
||||
{
|
||||
if (self != NULL)
|
||||
{
|
||||
char *s = gsk_transform_to_string (self);
|
||||
g_warning ("Given transform \"%s\" is not a 2D transform.", s);
|
||||
g_free (s);
|
||||
}
|
||||
*out_xx = 1.0f;
|
||||
*out_yx = 0.0f;
|
||||
*out_xy = 0.0f;
|
||||
*out_yy = 1.0f;
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
char *s = gsk_transform_to_string (self);
|
||||
g_warning ("Given transform \"%s\" is not a 2D transform.", s);
|
||||
g_free (s);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1544,41 +1544,25 @@ gsk_transform_to_affine (GskTransform *self,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
*out_scale_x = 1.0f;
|
||||
*out_scale_y = 1.0f;
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
|
||||
if (self == NULL)
|
||||
{
|
||||
*out_scale_x = 1.0f;
|
||||
*out_scale_y = 1.0f;
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
if (G_UNLIKELY (self->category < GSK_TRANSFORM_CATEGORY_2D_AFFINE))
|
||||
{
|
||||
char *s = gsk_transform_to_string (self);
|
||||
g_warning ("Given transform \"%s\" is not an affine 2D transform.", s);
|
||||
g_free (s);
|
||||
|
||||
*out_scale_x = 1.0f;
|
||||
*out_scale_y = 1.0f;
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->next != NULL)
|
||||
{
|
||||
gsk_transform_to_affine (self->next,
|
||||
out_scale_x, out_scale_y,
|
||||
out_dx, out_dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
*out_scale_x = 1.0f;
|
||||
*out_scale_y = 1.0f;
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
}
|
||||
gsk_transform_to_affine (self->next,
|
||||
out_scale_x, out_scale_y,
|
||||
out_dx, out_dy);
|
||||
|
||||
self->transform_class->apply_affine (self,
|
||||
out_scale_x, out_scale_y,
|
||||
@@ -1607,12 +1591,11 @@ gsk_transform_to_translate (GskTransform *self,
|
||||
float *out_dx,
|
||||
float *out_dy)
|
||||
{
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
|
||||
if (self == NULL)
|
||||
{
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
if (G_UNLIKELY (self->category < GSK_TRANSFORM_CATEGORY_2D_TRANSLATE))
|
||||
{
|
||||
@@ -1620,24 +1603,12 @@ gsk_transform_to_translate (GskTransform *self,
|
||||
g_warning ("Given transform \"%s\" is not an affine 2D translation.", s);
|
||||
g_free (s);
|
||||
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->next != NULL)
|
||||
{
|
||||
gsk_transform_to_translate (self->next,
|
||||
out_dx, out_dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
*out_dx = 0.0f;
|
||||
*out_dy = 0.0f;
|
||||
}
|
||||
gsk_transform_to_translate (self->next, out_dx, out_dy);
|
||||
|
||||
self->transform_class->apply_translate (self,
|
||||
out_dx, out_dy);
|
||||
self->transform_class->apply_translate (self, out_dx, out_dy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ float_to_half (const float x)
|
||||
return (b&0x80000000)>>16 | (e>112)*((((e-112)<<10)&0x7C00)|m>>13) | ((e<113)&(e>101))*((((0x007FF000+m)>>(125-e))+1)>>1) | (e>143)*0x7FFF; // sign : normalized : denormalized : saturate
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
float_to_half4_c (const float f[4],
|
||||
guint16 h[4])
|
||||
{
|
||||
@@ -64,7 +64,7 @@ float_to_half4_c (const float f[4],
|
||||
h[3] = float_to_half (f[3]);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
half_to_float4_c (const guint16 h[4],
|
||||
float f[4])
|
||||
{
|
||||
|
||||
@@ -41,6 +41,12 @@ void float_to_half4_f16c (const float f[4],
|
||||
void half_to_float4_f16c (const guint16 h[4],
|
||||
float f[4]);
|
||||
|
||||
void float_to_half4_c (const float f[4],
|
||||
guint16 h[4]);
|
||||
|
||||
void half_to_float4_c (const guint16 h[4],
|
||||
float f[4]);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1376,7 +1376,7 @@ gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
|
||||
|
||||
bpp = gdk_memory_format_bytes_per_pixel (data_format);
|
||||
|
||||
/* Swtich to texture0 as 2D. We'll restore it later. */
|
||||
/* Switch to texture0 as 2D. We'll restore it later. */
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user