Compare commits
424 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5cb7e60c73 | |||
| f9194042f4 | |||
| 5c4aba4b9c | |||
| 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 | |||
| 6efe31e6f5 | |||
| 9885bedb7d | |||
| b6edb517e4 | |||
| f023695f31 | |||
| 749ea8c30c | |||
| c79f289d67 | |||
| e516ce428a | |||
| 1ae259aecb | |||
| c609e2fef9 | |||
| 8ff9c851ce | |||
| 5ef2b9fd54 | |||
| 511dc7a182 | |||
| c668586caf | |||
| 390447862a | |||
| 7f2648a013 | |||
| 3227aa2c45 | |||
| c88dc98b7c | |||
| ed5b42071c | |||
| 804d9ee828 | |||
| a90f721b74 | |||
| 106417ada7 | |||
| fd0d3283e0 | |||
| 3e63e683a9 | |||
| e415f25c8f | |||
| e596e1fa7d | |||
| d8ab2e6d03 | |||
| e9d3d3e3cf | |||
| 3a5983e387 | |||
| 4efb661ae6 | |||
| bcdb9c937c | |||
| f45c0b9609 | |||
| 9ea162034a | |||
| 192e779db2 | |||
| bda7557783 | |||
| dc50c7539a | |||
| bf97dfd998 | |||
| c7f4131402 | |||
| bd5e5beee0 | |||
| 7a493f151d | |||
| 0ea73c384f | |||
| d8c416e8b2 | |||
| 9bf3724d25 | |||
| fd49d39184 | |||
| 0fd790eb8d | |||
| b18e95d6b3 | |||
| 47b5c68df4 | |||
| ac3b246858 | |||
| 51a754547e | |||
| 76df60db2b | |||
| f3befe530b | |||
| 59d4333e23 | |||
| 92177d9663 | |||
| 6a29b64850 | |||
| 73cb60d053 | |||
| 47bd998e94 | |||
| e2cfa7bd11 | |||
| 006633082d | |||
| bbf7454fc9 | |||
| 85cb5509c4 | |||
| 0e29f52841 | |||
| 02893e37d3 | |||
| 1dbb5188ba | |||
| a4d35ace78 | |||
| 981a638b01 | |||
| 3969d8b028 | |||
| 889709213e | |||
| 333a92bcff | |||
| cd39e417e1 | |||
| 1cebf406aa | |||
| d7915fbca8 | |||
| 9169315cc1 | |||
| 3b70cd3226 | |||
| a6101f0181 | |||
| 92c6485adf | |||
| 4df9314039 | |||
| c8ad4d5deb | |||
| 13a2db2238 | |||
| e8f9fb0f86 | |||
| 634bd2de48 | |||
| f58fc6b22e | |||
| fb052c8d25 | |||
| e35490ba5b | |||
| be1b979e51 | |||
| 3fd931d392 | |||
| 6c1dce2878 | |||
| ad1260505d | |||
| d92f8a1b8e | |||
| 22827f2cc7 | |||
| b64370cd48 | |||
| 6c8e176cc0 | |||
| 057bda6cd7 | |||
| 8df2cce5c1 | |||
| 352898ae9e | |||
| 1bda665662 | |||
| fad4c60499 | |||
| 47bb556327 | |||
| 4d00f1903a | |||
| 7344a03aa3 | |||
| 64af90111e | |||
| 3254a3feab | |||
| d5054f9b99 | |||
| db93090ea8 | |||
| 15c65595b8 | |||
| e59e9ad6a9 | |||
| e6c4dbfc6d | |||
| 424dd8a463 | |||
| 7b1a7629bc | |||
| df1116a010 | |||
| 11916bac7e | |||
| d675ae5cc5 | |||
| 43eeff8f15 | |||
| ece9e7e240 | |||
| 1abbf00dcf | |||
| 10564514e8 | |||
| ba7ec29dc0 | |||
| 85b595bd14 | |||
| 56c486abbf | |||
| 96fc5dc3a7 | |||
| b09087d634 | |||
| 5e99513507 | |||
| 0a9d2f248e | |||
| 16ff055b42 | |||
| 89f57d4ff6 | |||
| c4a2234a28 | |||
| a3882763d8 | |||
| 787fa6bd0d | |||
| a6b4e53dca | |||
| 00d25ae89c | |||
| 5776fcd955 | |||
| 86b5dba43b | |||
| e888364d3c | |||
| 276f85c9e3 | |||
| 68eb422333 | |||
| c0f54f899d | |||
| 65212535df | |||
| 106ac7c782 | |||
| bc7b6a0e53 | |||
| e5b89569fd | |||
| 938bfff3dd | |||
| 6835fcf3cf | |||
| 2554ee27d9 | |||
| 007cdf8787 | |||
| a526daf310 | |||
| ee34e1acc5 | |||
| a08fbfa586 | |||
| d29f57fd1d | |||
| a4c5d1d94d | |||
| 17f1bb1632 | |||
| 3418504b4b | |||
| 0a78a592ff | |||
| 208c527fb3 | |||
| 28990285e2 | |||
| c7ad8d29e9 | |||
| dba8d1ff77 | |||
| 143770f16d | |||
| 8a890238f5 | |||
| 71be3a8de1 | |||
| 17373c3e77 | |||
| 078ada75d4 | |||
| 51a60b88b7 | |||
| 193903ce4a | |||
| 386002597b | |||
| e5a6d4a1c8 | |||
| 06caa57f9a | |||
| 5ef6944a41 | |||
| 2e415e266f | |||
| 970bb804de | |||
| 915388cfdb | |||
| 1bf7f5eacb | |||
| 6a86acb9ce | |||
| e35e7bcd4a | |||
| 517b5173f9 | |||
| 37acfcfcd5 | |||
| c2f2a45227 | |||
| 621e0a13e9 | |||
| 92fcd37a19 | |||
| d8bde48b87 | |||
| 825ffb9422 | |||
| 046ef010b3 | |||
| b71ec6cb59 | |||
| b1beb3650b | |||
| fca19e72ad | |||
| 98d2320c93 | |||
| effc7a619d | |||
| 0ec017fcc0 | |||
| 94ad177176 | |||
| 4616104742 | |||
| a3a24b81c8 | |||
| debcc62775 | |||
| b11f31afea | |||
| db2e5648c9 | |||
| 46d1f04a7c | |||
| fe774c1ad8 | |||
| 08ee36e7c4 | |||
| 1605ec0a44 | |||
| 4b46e11b22 | |||
| 9993e91add | |||
| 9ac22c1088 | |||
| 47400e4bd8 | |||
| 8981ba4bd2 | |||
| 74a41eeb70 | |||
| ff874318c0 | |||
| a4598567b9 | |||
| 8f95661167 | |||
| e437c55142 | |||
| ff01067b8b | |||
| 7f4630abac | |||
| 4c9bd6ed9a | |||
| b6cd97be1e | |||
| c4cbd6ec1b | |||
| 312289fb11 | |||
| 036dd60a4e | |||
| 10c6c93f40 | |||
| 4d894e08f7 | |||
| 31407d0a4c | |||
| bb53cf53e7 | |||
| da9cd4659e | |||
| d3e6e303fc | |||
| a0c23b1c3d | |||
| 50b3a952c8 | |||
| 15b24a000d | |||
| 6a509608f9 | |||
| df6a52520c | |||
| 578db92973 | |||
| 3ab97fac1f | |||
| e8852c9a25 | |||
| fa0b379d30 | |||
| 1565053842 | |||
| 8288d9e87c | |||
| a900b30bcf | |||
| 9b671d1f79 | |||
| c2d82c23e6 | |||
| a88b4f517e | |||
| f9f9fa6dc6 | |||
| 02672a521a | |||
| a74420bc1a | |||
| 8789e78796 | |||
| 82b11623f4 |
+13
-5
@@ -24,9 +24,8 @@ variables:
|
|||||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v31"
|
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v32"
|
||||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v31"
|
|
||||||
|
|
||||||
.only-default:
|
.only-default:
|
||||||
only:
|
only:
|
||||||
@@ -60,6 +59,7 @@ style-check-diff:
|
|||||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
|
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
||||||
|
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
paths:
|
paths:
|
||||||
@@ -79,9 +79,14 @@ fedora-x86_64:
|
|||||||
script:
|
script:
|
||||||
- .gitlab-ci/show-info-linux.sh
|
- .gitlab-ci/show-info-linux.sh
|
||||||
- meson subprojects update
|
- meson subprojects update
|
||||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
- mkdir _install
|
||||||
|
- meson --prefix=${CI_PROJECT_DIR}/_install
|
||||||
|
${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||||
_build
|
_build
|
||||||
- ninja -C _build
|
- meson compile -C _build
|
||||||
|
- meson install -C _build
|
||||||
|
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
|
||||||
|
- meson compile -C _build_hello
|
||||||
- .gitlab-ci/run-tests.sh _build x11
|
- .gitlab-ci/run-tests.sh _build x11
|
||||||
- .gitlab-ci/run-tests.sh _build wayland
|
- .gitlab-ci/run-tests.sh _build wayland
|
||||||
- .gitlab-ci/run-tests.sh _build broadway
|
- .gitlab-ci/run-tests.sh _build broadway
|
||||||
@@ -165,6 +170,9 @@ macos:
|
|||||||
- export MESON_FORCE_BACKTRACE=1
|
- export MESON_FORCE_BACKTRACE=1
|
||||||
script:
|
script:
|
||||||
- meson -Dx11-backend=false
|
- meson -Dx11-backend=false
|
||||||
|
-Dbroadway-backend=true
|
||||||
|
-Dmacos-backend=true
|
||||||
|
-Dmedia-gstreamer=disabled
|
||||||
-Dintrospection=disabled
|
-Dintrospection=disabled
|
||||||
-Dcpp_std=c++11
|
-Dcpp_std=c++11
|
||||||
-Dpixman:tests=disabled
|
-Dpixman:tests=disabled
|
||||||
@@ -302,7 +310,7 @@ asan-build:
|
|||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
reference:
|
reference:
|
||||||
image: $DOCS_IMAGE
|
image: $FEDORA_IMAGE
|
||||||
stage: docs
|
stage: docs
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ RUN dnf -y install \
|
|||||||
gstreamer1-plugins-good \
|
gstreamer1-plugins-good \
|
||||||
gstreamer1-plugins-bad-free-devel \
|
gstreamer1-plugins-bad-free-devel \
|
||||||
gstreamer1-plugins-base-devel \
|
gstreamer1-plugins-base-devel \
|
||||||
gtk-doc \
|
|
||||||
hicolor-icon-theme \
|
hicolor-icon-theme \
|
||||||
iso-codes \
|
iso-codes \
|
||||||
itstool \
|
itstool \
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ meson \
|
|||||||
-Dx11-backend=true \
|
-Dx11-backend=true \
|
||||||
-Dwayland-backend=true \
|
-Dwayland-backend=true \
|
||||||
-Dbroadway-backend=true \
|
-Dbroadway-backend=true \
|
||||||
-Dvulkan=yes \
|
-Dvulkan=enabled \
|
||||||
-Dprofiler=true \
|
-Dprofiler=true \
|
||||||
--werror \
|
--werror \
|
||||||
${EXTRA_MESON_FLAGS:-} \
|
${EXTRA_MESON_FLAGS:-} \
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
|||||||
|
|
||||||
:: FIXME: make warnings fatal
|
:: FIXME: make warnings fatal
|
||||||
pip3 install --upgrade --user meson==0.56.2 || goto :error
|
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
|
ninja -C _build || goto :error
|
||||||
|
|
||||||
goto :EOF
|
goto :EOF
|
||||||
|
|||||||
@@ -1,3 +1,213 @@
|
|||||||
|
Overview of Changes in 4.3.2
|
||||||
|
============================
|
||||||
|
|
||||||
|
* GtkToggleButton:
|
||||||
|
- Fix the actionable implementation
|
||||||
|
|
||||||
|
* GtkCheckButton:
|
||||||
|
- Fix the actionable implementation
|
||||||
|
- Cancel activation on when the pointer leaves
|
||||||
|
|
||||||
|
* GtkMenuButton:
|
||||||
|
- Make activatable again
|
||||||
|
- Add a way to have an icon + arrow
|
||||||
|
|
||||||
|
* GtkColorButton:
|
||||||
|
- Make activatable again
|
||||||
|
|
||||||
|
* GtkFontButton:
|
||||||
|
- Make activatable again
|
||||||
|
|
||||||
|
* GtkAppChooserButton:
|
||||||
|
- Make activatable again
|
||||||
|
|
||||||
|
* GtkColumnView:
|
||||||
|
- Fix double activation
|
||||||
|
|
||||||
|
* GtkLabel:
|
||||||
|
- Fix mnemonics without markup
|
||||||
|
|
||||||
|
* GtkTreeView:
|
||||||
|
- Clip header buttons
|
||||||
|
|
||||||
|
* GtkTextView:
|
||||||
|
- Add api to get the RTL and LTR contexts
|
||||||
|
- Fix some errors in text history grouping
|
||||||
|
|
||||||
|
* GtkText:
|
||||||
|
- Don't show placeholder text on top of entry text
|
||||||
|
- Add api to compute the cursor extents
|
||||||
|
- Fix y coordinates for text selection
|
||||||
|
|
||||||
|
* GtkFileChooser:
|
||||||
|
- Don't show Trash in the side bar
|
||||||
|
|
||||||
|
* GtkPopoverMenu:
|
||||||
|
- Add scrollbars to long menus
|
||||||
|
|
||||||
|
* GtkActionMuxer:
|
||||||
|
- Fix propagation of accel changes
|
||||||
|
|
||||||
|
* Introspection:
|
||||||
|
- Annotate all filename arguments
|
||||||
|
- Rename GtkMediaStream apis to avoid name collisions
|
||||||
|
- Rename GtkDropTarget properties to avoid name collisions
|
||||||
|
- Make GtkPasswordEntryBuffer introspectable
|
||||||
|
|
||||||
|
* Printing:
|
||||||
|
- Remove the Google Cloud Print backend
|
||||||
|
|
||||||
|
* Theme:
|
||||||
|
- Sync included icons with the Adwaita icon theme
|
||||||
|
|
||||||
|
* GSK:
|
||||||
|
- Avoid overflowing the vertex counter
|
||||||
|
- Handle negative scales correctly in the ngl renderer
|
||||||
|
|
||||||
|
* GDK:
|
||||||
|
- Cleanup and simplify OpenGL setup code
|
||||||
|
- Add a GdkDisplay::init_gl vfunc and gdk_display_prepare_gl() api
|
||||||
|
- Require EGL 1.4
|
||||||
|
- Fix EGL + NVidia
|
||||||
|
|
||||||
|
* Build:
|
||||||
|
- Enable gstreamer by default
|
||||||
|
- Disable Vulkan by default
|
||||||
|
- Remove the sassc option
|
||||||
|
- Remove options and checks for X11 extensions
|
||||||
|
|
||||||
|
* X11:
|
||||||
|
- Stop using XComposite
|
||||||
|
- Remove the Visual cache
|
||||||
|
|
||||||
|
* Wayland:
|
||||||
|
- Fix some DND corner cases
|
||||||
|
- Work with version 2 of pointer-gestures-v1
|
||||||
|
- Look for cursor themes in $HOME/.icons
|
||||||
|
|
||||||
|
* Windows:
|
||||||
|
- Fix SIGILL on x64 due to popcnt
|
||||||
|
- Fix popup placement
|
||||||
|
- Fix drag icon placement
|
||||||
|
- Clean up HiDPI and WGL support
|
||||||
|
- Default to WGL
|
||||||
|
|
||||||
|
* MacOs:
|
||||||
|
- Fix input method support
|
||||||
|
- Register known clipboard types for drop targets
|
||||||
|
- Add initial DND support
|
||||||
|
|
||||||
|
* Translation updates:
|
||||||
|
Brazilian Portuguese
|
||||||
|
Portuguese
|
||||||
|
Romanian
|
||||||
|
Turkish
|
||||||
|
Ukrainian
|
||||||
|
|
||||||
|
|
||||||
|
Overview of Changes in 4.3.1
|
||||||
|
============================
|
||||||
|
|
||||||
|
* GtkEmojiChooser:
|
||||||
|
- Update data from CLDR 39
|
||||||
|
- Load Emoji data for both language and territory
|
||||||
|
|
||||||
|
* GtkCalendar:
|
||||||
|
- Fix an off-by-one error in day numbers
|
||||||
|
|
||||||
|
* GtkListView:
|
||||||
|
- Add .activatable style class to activatable items
|
||||||
|
|
||||||
|
* GtkCheckButton:
|
||||||
|
- Don't allow unchecking grouped radio buttons
|
||||||
|
|
||||||
|
*GtkToggleButton:
|
||||||
|
- Fix mnemonic activation propagation
|
||||||
|
|
||||||
|
* GtkLabel:
|
||||||
|
- Make mnemonics work even when invisible
|
||||||
|
- Fix mnemonic activation propagation
|
||||||
|
|
||||||
|
* GtkMenuButton:
|
||||||
|
- Add a property to mark primary menus and make F10 work
|
||||||
|
|
||||||
|
* GtkApplication:
|
||||||
|
- Fix initial screensaver state async
|
||||||
|
|
||||||
|
* GtkEntry:
|
||||||
|
- Apply xalign to placeholder text (as it was in GTK 3)
|
||||||
|
|
||||||
|
* GtkSpinButton:
|
||||||
|
- Fix swipe gestures
|
||||||
|
|
||||||
|
* GtkStackSwitcher:
|
||||||
|
- Implement GtkOrientable (as it was in GTK 3)
|
||||||
|
- Fix a use-after-free problem with drag timeouts
|
||||||
|
|
||||||
|
* GtkFileChooser:
|
||||||
|
- Add support for (case-insensitive) suffix matches in GtkFileFilter
|
||||||
|
|
||||||
|
* GtkPasswordEntry:
|
||||||
|
- Make GtkPasswordEntryBuffer public, to make it easier
|
||||||
|
to write your own password entry widget
|
||||||
|
|
||||||
|
* Input:
|
||||||
|
- Fix interference between various obscure XKB features
|
||||||
|
(e.g. overlays) and Compose sequences
|
||||||
|
|
||||||
|
* Action support:
|
||||||
|
- Fix submenu-action handling
|
||||||
|
|
||||||
|
* Theme:
|
||||||
|
- Update icons from the Adwaita icon theme
|
||||||
|
- Fix icon names for GtkSwitch
|
||||||
|
- Fix switch-off icon
|
||||||
|
|
||||||
|
* GSK:
|
||||||
|
- Improve transformed offscreen rendering
|
||||||
|
- Add padding between cached glyphs
|
||||||
|
|
||||||
|
* Wayland:
|
||||||
|
- Fix monitor sizes in the presence of transforms
|
||||||
|
- Add a getter for the EGLDisplay
|
||||||
|
- Fix click-drag-release sequences for popovers
|
||||||
|
|
||||||
|
* X11:
|
||||||
|
- Support EGL for X11. Fall back to GLX if EGL isn't available
|
||||||
|
- Always fall back to GLX on NVidia
|
||||||
|
- Add a getter for the EGLDisplay
|
||||||
|
|
||||||
|
* Broadway:
|
||||||
|
- Add a setter for display scale
|
||||||
|
|
||||||
|
* Windows:
|
||||||
|
- Add a getter for the EGLDisplay
|
||||||
|
- Make GL work for media playback
|
||||||
|
|
||||||
|
* MacOS:
|
||||||
|
- Fix menubar appearance
|
||||||
|
|
||||||
|
* Tools:
|
||||||
|
- gtk4-builder-tool: Replace can-focus with focusable in 3-to-4 conversion
|
||||||
|
|
||||||
|
* Introspection:
|
||||||
|
- Add missing annotations in a few places (e.g. gtk_free_view_row_activated)
|
||||||
|
|
||||||
|
* Build:
|
||||||
|
- Only build one source file with -mf16c
|
||||||
|
- Fix devel styling for ci flatpak builds
|
||||||
|
- Generate appdata for demo flatpaks
|
||||||
|
|
||||||
|
* Docs:
|
||||||
|
- Numerous fixes and additions
|
||||||
|
|
||||||
|
* Translation updates:
|
||||||
|
Friulian
|
||||||
|
Nepali
|
||||||
|
Norwegian Bokmål
|
||||||
|
Ukrainian
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in 4.3.0
|
Overview of Changes in 4.3.0
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
|||||||
@@ -157,8 +157,8 @@ Release notes
|
|||||||
The release notes for GTK are part of the migration guide in the API
|
The release notes for GTK are part of the migration guide in the API
|
||||||
reference. See:
|
reference. See:
|
||||||
|
|
||||||
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
|
- [3.x release notes](https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html)
|
||||||
- [4.x release notes](https://developer.gnome.org/gtk4/unstable/gtk-migrating-3-to-4.html)
|
- [4.x release notes](https://docs.gtk.org/gtk4/migrating-3to4.html)
|
||||||
|
|
||||||
Licensing terms
|
Licensing terms
|
||||||
---------------
|
---------------
|
||||||
|
|||||||
@@ -124,9 +124,6 @@
|
|||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
#mesondefine HAVE_UNISTD_H
|
#mesondefine HAVE_UNISTD_H
|
||||||
|
|
||||||
/* Have the XCOMPOSITE X extension */
|
|
||||||
#mesondefine HAVE_XCOMPOSITE
|
|
||||||
|
|
||||||
/* Have the Xcursor library */
|
/* Have the Xcursor library */
|
||||||
#mesondefine HAVE_XCURSOR
|
#mesondefine HAVE_XCURSOR
|
||||||
|
|
||||||
|
|||||||
@@ -163,8 +163,8 @@ drag_update_cb (GtkGestureDrag *drag,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
drag_end_cb (GtkGestureDrag *drag,
|
drag_end_cb (GtkGestureDrag *drag,
|
||||||
gdouble dx,
|
double dx,
|
||||||
gdouble dy,
|
double dy,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
|
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
|
||||||
|
|||||||
+15
-1
@@ -21,8 +21,10 @@ do_menu (GtkWidget *do_widget)
|
|||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
|
GtkWidget *box;
|
||||||
GtkWidget *sw;
|
GtkWidget *sw;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
|
GtkWidget *scale;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
||||||
@@ -31,11 +33,23 @@ do_menu (GtkWidget *do_widget)
|
|||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
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 ();
|
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");
|
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
|
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))
|
if (!gtk_widget_get_visible (window))
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<component type="desktop">
|
<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>
|
<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>
|
<name>GTK Demo</name>
|
||||||
<summary>Program to demonstrate GTK functions</summary>
|
<summary>Program to demonstrate GTK functions</summary>
|
||||||
<description>
|
<description>
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
<translation type="gettext">gtk-4.0</translation>
|
<translation type="gettext">gtk-4.0</translation>
|
||||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||||
<developer_name>Matthias Clasen and others</developer_name>
|
<developer_name>Matthias Clasen and others</developer_name>
|
||||||
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||||
<description>
|
<description>
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ gtk_nuclear_media_stream_step (gpointer data)
|
|||||||
* call our pause function to pause the stream.
|
* call our pause function to pause the stream.
|
||||||
*/
|
*/
|
||||||
if (nuclear->progress >= DURATION)
|
if (nuclear->progress >= DURATION)
|
||||||
gtk_media_stream_ended (GTK_MEDIA_STREAM (nuclear));
|
gtk_media_stream_stream_ended (GTK_MEDIA_STREAM (nuclear));
|
||||||
|
|
||||||
/* The timeout function is removed by the pause function,
|
/* The timeout function is removed by the pause function,
|
||||||
* so we can just always return this value.
|
* so we can just always return this value.
|
||||||
@@ -267,11 +267,11 @@ gtk_nuclear_media_stream_init (GtkNuclearMediaStream *nuclear)
|
|||||||
* However, media streams need to tell GTK once they are initialized,
|
* However, media streams need to tell GTK once they are initialized,
|
||||||
* so we do that here.
|
* so we do that here.
|
||||||
*/
|
*/
|
||||||
gtk_media_stream_prepared (GTK_MEDIA_STREAM (nuclear),
|
gtk_media_stream_stream_prepared (GTK_MEDIA_STREAM (nuclear),
|
||||||
FALSE,
|
FALSE,
|
||||||
TRUE,
|
TRUE,
|
||||||
TRUE,
|
TRUE,
|
||||||
DURATION);
|
DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And finally, we add the simple constructor we declared in the header. */
|
/* And finally, we add the simple constructor we declared in the header. */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Peg Solitaire
|
/* Peg Solitaire
|
||||||
* #Keywords: GtkGridView, game
|
* #Keywords: GtkGridView, game
|
||||||
*
|
*
|
||||||
* This demo demonstrates how to use drag'n'drop to implement peg solitaire.
|
* This demo demonstrates how to use drag-and-drop to implement peg solitaire.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ solitaire_peg_init (SolitairePeg *peg)
|
|||||||
|
|
||||||
/* Add a little setter for the peg's position.
|
/* Add a little setter for the peg's position.
|
||||||
* We want to track those so that we can check for legal moves
|
* We want to track those so that we can check for legal moves
|
||||||
* during drag'n'drop operations.
|
* during drag-and-drop operations.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
solitaire_peg_set_position (SolitairePeg *peg,
|
solitaire_peg_set_position (SolitairePeg *peg,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<component type="desktop">
|
<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>
|
<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>
|
<name>GTK Icon Browser</name>
|
||||||
<summary>Program to browse themed icons</summary>
|
<summary>Program to browse themed icons</summary>
|
||||||
<description>
|
<description>
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
<translation type="gettext">gtk-4.0</translation>
|
<translation type="gettext">gtk-4.0</translation>
|
||||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||||
<developer_name>Matthias Clasen and others</developer_name>
|
<developer_name>Matthias Clasen and others</developer_name>
|
||||||
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||||
<description>
|
<description>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<component type="desktop">
|
<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>
|
<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>
|
<name>GTK Print Editor</name>
|
||||||
<summary>Program to demonstrate GTK printing</summary>
|
<summary>Program to demonstrate GTK printing</summary>
|
||||||
<description>
|
<description>
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
<translation type="gettext">gtk-4.0</translation>
|
<translation type="gettext">gtk-4.0</translation>
|
||||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||||
<developer_name>Matthias Clasen and others</developer_name>
|
<developer_name>Matthias Clasen and others</developer_name>
|
||||||
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="3.99.0" date="2020-07-30">
|
<release version="3.99.0" date="2020-07-30">
|
||||||
<description>
|
<description>
|
||||||
|
|||||||
@@ -721,7 +721,6 @@ static const char ui_info[] =
|
|||||||
" <item>"
|
" <item>"
|
||||||
" <attribute name='label'>_New</attribute>"
|
" <attribute name='label'>_New</attribute>"
|
||||||
" <attribute name='action'>app.new</attribute>"
|
" <attribute name='action'>app.new</attribute>"
|
||||||
" <attribute name='accel'><Primary>n</attribute>"
|
|
||||||
" </item>"
|
" </item>"
|
||||||
" <item>"
|
" <item>"
|
||||||
" <attribute name='label'>_Open</attribute>"
|
" <attribute name='label'>_Open</attribute>"
|
||||||
@@ -730,12 +729,10 @@ static const char ui_info[] =
|
|||||||
" <item>"
|
" <item>"
|
||||||
" <attribute name='label'>_Save</attribute>"
|
" <attribute name='label'>_Save</attribute>"
|
||||||
" <attribute name='action'>app.save</attribute>"
|
" <attribute name='action'>app.save</attribute>"
|
||||||
" <attribute name='accel'><Primary>s</attribute>"
|
|
||||||
" </item>"
|
" </item>"
|
||||||
" <item>"
|
" <item>"
|
||||||
" <attribute name='label'>Save _As...</attribute>"
|
" <attribute name='label'>Save _As...</attribute>"
|
||||||
" <attribute name='action'>app.save-as</attribute>"
|
" <attribute name='action'>app.save-as</attribute>"
|
||||||
" <attribute name='accel'><Primary>s</attribute>"
|
|
||||||
" </item>"
|
" </item>"
|
||||||
" </section>"
|
" </section>"
|
||||||
" <section>"
|
" <section>"
|
||||||
@@ -756,7 +753,6 @@ static const char ui_info[] =
|
|||||||
" <item>"
|
" <item>"
|
||||||
" <attribute name='label'>_Quit</attribute>"
|
" <attribute name='label'>_Quit</attribute>"
|
||||||
" <attribute name='action'>app.quit</attribute>"
|
" <attribute name='action'>app.quit</attribute>"
|
||||||
" <attribute name='accel'><Primary>q</attribute>"
|
|
||||||
" </item>"
|
" </item>"
|
||||||
" </section>"
|
" </section>"
|
||||||
" </submenu>"
|
" </submenu>"
|
||||||
@@ -766,7 +762,6 @@ static const char ui_info[] =
|
|||||||
" <item>"
|
" <item>"
|
||||||
" <attribute name='label'>_About Print Editor</attribute>"
|
" <attribute name='label'>_About Print Editor</attribute>"
|
||||||
" <attribute name='action'>app.about</attribute>"
|
" <attribute name='action'>app.about</attribute>"
|
||||||
" <attribute name='accel'><Primary>a</attribute>"
|
|
||||||
" </item>"
|
" </item>"
|
||||||
" </section>"
|
" </section>"
|
||||||
" </submenu>"
|
" </submenu>"
|
||||||
@@ -794,6 +789,15 @@ startup (GApplication *app)
|
|||||||
{
|
{
|
||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
GMenuModel *menubar;
|
GMenuModel *menubar;
|
||||||
|
struct {
|
||||||
|
const char *action_and_target;
|
||||||
|
const char *accelerators[2];
|
||||||
|
} accels[] = {
|
||||||
|
{ "app.new", { "<Control>n", NULL } },
|
||||||
|
{ "app.quit", { "<Control>q", NULL } },
|
||||||
|
{ "app.save", { "<Control>s", NULL } },
|
||||||
|
{ "app.about", { "<Control>a", NULL } },
|
||||||
|
};
|
||||||
|
|
||||||
builder = gtk_builder_new ();
|
builder = gtk_builder_new ();
|
||||||
gtk_builder_add_from_string (builder, ui_info, -1, NULL);
|
gtk_builder_add_from_string (builder, ui_info, -1, NULL);
|
||||||
@@ -802,6 +806,9 @@ startup (GApplication *app)
|
|||||||
|
|
||||||
gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
|
gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
|
||||||
|
|
||||||
|
for (int i = 0; i < G_N_ELEMENTS (accels); i++)
|
||||||
|
gtk_application_set_accels_for_action (GTK_APPLICATION (app), accels[i].action_and_target, accels[i].accelerators);
|
||||||
|
|
||||||
g_object_unref (builder);
|
g_object_unref (builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<component type="desktop">
|
<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>
|
<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>
|
<name>GTK Widget Factory</name>
|
||||||
<summary>Program to demonstrate GTK functions</summary>
|
<summary>Program to demonstrate GTK functions</summary>
|
||||||
<description>
|
<description>
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
<translation type="gettext">gtk-4.0</translation>
|
<translation type="gettext">gtk-4.0</translation>
|
||||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||||
<developer_name>Matthias Clasen and others</developer_name>
|
<developer_name>Matthias Clasen and others</developer_name>
|
||||||
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||||
<description>
|
<description>
|
||||||
|
|||||||
@@ -1997,6 +1997,7 @@ activate (GApplication *app)
|
|||||||
const char *accelerators[2];
|
const char *accelerators[2];
|
||||||
} accels[] = {
|
} accels[] = {
|
||||||
{ "app.about", { "F1", NULL } },
|
{ "app.about", { "F1", NULL } },
|
||||||
|
{ "app.shortcuts", { "<Control>question", NULL } },
|
||||||
{ "app.quit", { "<Control>q", NULL } },
|
{ "app.quit", { "<Control>q", NULL } },
|
||||||
{ "app.open-in", { "<Control>n", NULL } },
|
{ "app.open-in", { "<Control>n", NULL } },
|
||||||
{ "win.dark", { "<Control>d", NULL } },
|
{ "win.dark", { "<Control>d", NULL } },
|
||||||
|
|||||||
@@ -2902,7 +2902,7 @@ bad things might happen.</property>
|
|||||||
|
|
||||||
<action-widgets>
|
<action-widgets>
|
||||||
<action-widget response="cancel">cancel_info_dialog</action-widget>
|
<action-widget response="cancel">cancel_info_dialog</action-widget>
|
||||||
<action-widget response="ok">doit_info_dialog</action-widget>
|
<action-widget response="ok" default="true">doit_info_dialog</action-widget>
|
||||||
</action-widgets>
|
</action-widgets>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkDialog" id="action_dialog">
|
<object class="GtkDialog" id="action_dialog">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
|||||||
website_url = "https://www.gtk.org"
|
website_url = "https://www.gtk.org"
|
||||||
authors = "GTK Development Team"
|
authors = "GTK Development Team"
|
||||||
logo_url = "gtk-logo.svg"
|
logo_url = "gtk-logo.svg"
|
||||||
license = "GPL-2.1-or-later"
|
license = "LGPL-2.1-or-later"
|
||||||
description = "The GTK toolkit"
|
description = "The GTK toolkit"
|
||||||
dependencies = [ "GObject-2.0", "cairo-1.0", "Pango-1.0", "GdkWayland-4.0", "GdkX11-4.0" ]
|
dependencies = [ "GObject-2.0", "cairo-1.0", "Pango-1.0", "GdkWayland-4.0", "GdkX11-4.0" ]
|
||||||
devhelp = true
|
devhelp = true
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
|||||||
website_url = "https://www.gtk.org"
|
website_url = "https://www.gtk.org"
|
||||||
authors = "GTK Development Team"
|
authors = "GTK Development Team"
|
||||||
logo_url = "gtk-logo.svg"
|
logo_url = "gtk-logo.svg"
|
||||||
license = "GPL-2.1-or-later"
|
license = "LGPL-2.1-or-later"
|
||||||
description = "The GTK toolkit"
|
description = "The GTK toolkit"
|
||||||
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0" ]
|
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0" ]
|
||||||
devhelp = true
|
devhelp = true
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
Title: Drag-and-Drop in GTK
|
||||||
|
|
||||||
|
Drag-and-Drop (DND) is a user interaction pattern where users drag a UI element
|
||||||
|
from one place to another, either inside a single application or between
|
||||||
|
different application windows.
|
||||||
|
|
||||||
|
When the element is 'dropped', data is transferred from the source to the
|
||||||
|
destination, according to the drag action that is negotiated between both
|
||||||
|
sides. Most commonly, that is a _copy_, but it can also be a _move_ or a
|
||||||
|
_link_, depending on the kind of data and how the drag operation has been
|
||||||
|
set up.
|
||||||
|
|
||||||
|
This chapter gives an overview over how Drag-and-Drop is handled with event
|
||||||
|
controllers in GTK.
|
||||||
|
|
||||||
|
## Drag sources
|
||||||
|
|
||||||
|
To make data available via DND, you create a [class@Gtk.DragSource]. Drag sources
|
||||||
|
are event controllers, which initiate a Drag-and-Drop operation when the user clicks
|
||||||
|
and drags the widget.
|
||||||
|
|
||||||
|
A drag source can be set up ahead of time, with the desired drag action(s) and the data
|
||||||
|
to be transferred. But it is also possible to provide the data when a drag operation
|
||||||
|
is about to begin, by connecting to the [signal@Gtk.DragSource::prepare] signal.
|
||||||
|
|
||||||
|
The GtkDragSource emits the [signal@Gtk.DragSource::drag-begin] signal when the DND
|
||||||
|
operation starts, and the [signal@Gtk.DragSource::drag-end] signal when it is done.
|
||||||
|
But it is not normally necessary to handle these signals. One case in which a ::drag-end
|
||||||
|
handler is necessary is to implement `GDK_ACTION_MOVE`.
|
||||||
|
|
||||||
|
## Drop targets
|
||||||
|
|
||||||
|
To receive data via DND, you create a [class@Gtk.DropTarget], and tell it what kind of
|
||||||
|
data to accept. You need to connect to the [signal@Gtk.DropTarget::drop] signal to receive
|
||||||
|
the data when a DND operation occurs.
|
||||||
|
|
||||||
|
While a DND operation is ongoing, GTK provides updates when the pointer moves over
|
||||||
|
the widget to which the drop target is associated. The [signal@Gtk.DropTarget::enter],
|
||||||
|
[signal@Gtk.DropTarget::leave] and [signal@Gtk.DropTarget::motion] signals get emitted
|
||||||
|
for this purpose.
|
||||||
|
|
||||||
|
GtkDropTarget provides a simple API, and only provides the data when it has been completely
|
||||||
|
transferred. If you need to handle the data transfer yourself (for example to provide progress
|
||||||
|
information during the transfer), you can use the more complicated [class@Gtk.DropTargetAsync].
|
||||||
|
|
||||||
|
## Other considerations
|
||||||
|
|
||||||
|
It is sometimes necessary to update the UI of the destination while a DND operation is ongoing,
|
||||||
|
say to scroll or expand a view, or to switch pages. Typically, such UI changes are triggered
|
||||||
|
by hovering over the widget in question.
|
||||||
|
|
||||||
|
[class@Gtk.DropControllerMotion] is an event controller that can help with implementing such
|
||||||
|
behaviors. It is very similar to [class@Gtk.EventControllerMotion], but provides events during
|
||||||
|
a DND operation.
|
||||||
@@ -161,19 +161,19 @@ activate (GtkApplication *app,
|
|||||||
{
|
{
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
GtkWidget *box;
|
|
||||||
|
|
||||||
window = gtk_application_window_new (app);
|
window = gtk_application_window_new (app);
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label ("Hello World");
|
button = gtk_button_new_with_label ("Hello World");
|
||||||
|
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||||
|
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||||
|
|
||||||
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
||||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
||||||
gtk_box_append (GTK_BOX (box), button);
|
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), button);
|
||||||
|
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ display, unless specified otherwise.
|
|||||||
<para>
|
<para>
|
||||||
<command>gtk4-launch</command> takes at least one argument, the name of
|
<command>gtk4-launch</command> takes at least one argument, the name of
|
||||||
the application to launch. The name should match application desktop file name,
|
the application to launch. The name should match application desktop file name,
|
||||||
as residing in /usr/share/application, with or without the '.desktop' suffix.
|
as residing in the applications subdirectories of the XDG data directories, with
|
||||||
|
or without the '.desktop' suffix.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If called with more than one argument, the rest of them besides the application
|
If called with more than one argument, the rest of them besides the application
|
||||||
@@ -71,4 +72,14 @@ application.
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1><title>Environment</title>
|
||||||
|
<para>Some environment variables affect the behavior of <command>gtk4-launch</command>.</para>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>XDG_DATA_HOME</option>, <option>XDG_DATA_DIRS</option></term>
|
||||||
|
<listitem><para>The environment variables specifying the XDG dta directories.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
</refentry>
|
</refentry>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
|||||||
website_url = "https://www.gtk.org"
|
website_url = "https://www.gtk.org"
|
||||||
authors = "GTK Development Team"
|
authors = "GTK Development Team"
|
||||||
logo_url = "gtk-logo.svg"
|
logo_url = "gtk-logo.svg"
|
||||||
license = "GPL-2.1-or-later"
|
license = "LGPL-2.1-or-later"
|
||||||
description = "The GTK toolkit"
|
description = "The GTK toolkit"
|
||||||
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0", "Gsk-4.0" ]
|
dependencies = [ "GObject-2.0", "Graphene-1.0", "Pango-1.0", "Gdk-4.0", "Gsk-4.0" ]
|
||||||
devhelp = true
|
devhelp = true
|
||||||
@@ -57,6 +57,7 @@ content_files = [
|
|||||||
"initialization.md",
|
"initialization.md",
|
||||||
"actions.md",
|
"actions.md",
|
||||||
"input-handling.md",
|
"input-handling.md",
|
||||||
|
"drag-and-drop.md",
|
||||||
"drawing-model.md",
|
"drawing-model.md",
|
||||||
"css-overview.md",
|
"css-overview.md",
|
||||||
"css-properties.md",
|
"css-properties.md",
|
||||||
|
|||||||
@@ -99,6 +99,12 @@ you should stop using `GdkVisual` APIs, since this object not longer
|
|||||||
exists in GTK 4. Most of its APIs are deprecated already and not
|
exists in GTK 4. Most of its APIs are deprecated already and not
|
||||||
useful when dealing with RGBA visuals.
|
useful when dealing with RGBA visuals.
|
||||||
|
|
||||||
|
### Stop using `gtk_widget_set_app_paintable`
|
||||||
|
|
||||||
|
This is gone in GTK4 with no direct replacement. But for some usecases there
|
||||||
|
are alternatives. If you want to make the background transparent, you can set
|
||||||
|
the background color to, for example, `rgba(255, 255, 255, 0)` using CSS instead.
|
||||||
|
|
||||||
### Stop using `GtkBox` padding, fill and expand child properties
|
### Stop using `GtkBox` padding, fill and expand child properties
|
||||||
|
|
||||||
GTK 4 removes these [class@Gtk.Box] child properties, so you should stop using
|
GTK 4 removes these [class@Gtk.Box] child properties, so you should stop using
|
||||||
@@ -133,7 +139,7 @@ or `gtk_style_context_get_color()` only accept the context's current
|
|||||||
state for their state argument. You should update all callers to pass
|
state for their state argument. You should update all callers to pass
|
||||||
the current state.
|
the current state.
|
||||||
|
|
||||||
### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_surface()`
|
### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_window()`
|
||||||
|
|
||||||
These functions are not supported in GTK 4. Instead, either use
|
These functions are not supported in GTK 4. Instead, either use
|
||||||
backend-specific APIs, or render your widgets using
|
backend-specific APIs, or render your widgets using
|
||||||
@@ -187,11 +193,22 @@ for this change.
|
|||||||
| ::grab-broken-event | - |
|
| ::grab-broken-event | - |
|
||||||
|
|
||||||
Event signals which are not directly related to input have to be dealt with
|
Event signals which are not directly related to input have to be dealt with
|
||||||
on a one-by-one basis. If you were using `::configure-event` and
|
on a one-by-one basis:
|
||||||
`::window-state-event` to save window state, you should use property
|
|
||||||
notification for corresponding [class@Gtk.Window] properties, such as
|
- If you were using `::configure-event` and `::window-state-event` to save
|
||||||
[property@Gtk.Window:default-width], [property@Gtk.Window:default-height],
|
window state, you should use property notification for corresponding
|
||||||
[property@Gtk.Window:maximized] or [property@Gtk.Window:fullscreened].
|
[class@Gtk.Window] properties, such as [property@Gtk.Window:default-width],
|
||||||
|
[property@Gtk.Window:default-height], [property@Gtk.Window:maximized] or
|
||||||
|
[property@Gtk.Window:fullscreened].
|
||||||
|
- If you were using `::delete-event` to present a confirmation when using
|
||||||
|
the close button of a window, you should use the
|
||||||
|
[signal@Gtk.Window::close-request] signal.
|
||||||
|
- If you were using `::map-event` and `::unmap-event` to track a window
|
||||||
|
being mapped, you should use property notification for the
|
||||||
|
[property@Gdk.Surface:mapped] property instead.
|
||||||
|
- The `::damage-event` signal has no replacement, as the only consumer
|
||||||
|
of damage events were the offscreen GDK surfaces, which have no
|
||||||
|
replacement in GTK 4.x.
|
||||||
|
|
||||||
### Set a proper application ID
|
### Set a proper application ID
|
||||||
|
|
||||||
@@ -232,6 +249,10 @@ in GTK 3, you can prepare for the switch by using `gtk_widget_destroy()`
|
|||||||
only on toplevel windows, and replace all other uses with
|
only on toplevel windows, and replace all other uses with
|
||||||
`gtk_container_remove()` or `g_object_unref()`.
|
`gtk_container_remove()` or `g_object_unref()`.
|
||||||
|
|
||||||
|
### Stop using the GtkWidget.destroy vfunc
|
||||||
|
|
||||||
|
Instead of implementing GtkWidget.destroy, you can implement GObject.dispose.
|
||||||
|
|
||||||
### Reduce the use of generic container APIs
|
### Reduce the use of generic container APIs
|
||||||
|
|
||||||
GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there
|
GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there
|
||||||
@@ -604,6 +625,9 @@ from `FALSE` to `TRUE`. In addition, there is a [property@Gtk.Widget:focusable]
|
|||||||
property, which controls whether an individual widget can receive
|
property, which controls whether an individual widget can receive
|
||||||
the input focus.
|
the input focus.
|
||||||
|
|
||||||
|
The `gtk4-builder-tool` utility, when called with the `--3to4` option of the
|
||||||
|
`simplify` command, will replace `:can-focus` by `:focusable`.
|
||||||
|
|
||||||
The feature to automatically keep the focus widget scrolled into view with
|
The feature to automatically keep the focus widget scrolled into view with
|
||||||
`gtk_container_set_focus_vadjustment()` has been removed together with
|
`gtk_container_set_focus_vadjustment()` has been removed together with
|
||||||
`GtkContainer`, and is provided by scrollable widgets instead. In the common
|
`GtkContainer`, and is provided by scrollable widgets instead. In the common
|
||||||
@@ -740,7 +764,7 @@ The abstract base class `GtkBin` for single-child containers has been
|
|||||||
removed. The former subclasses are now derived directly from `GtkWidget`,
|
removed. The former subclasses are now derived directly from `GtkWidget`,
|
||||||
and have a "child" property for their child widget. To add a child, use
|
and have a "child" property for their child widget. To add a child, use
|
||||||
the setter for the "child" property (e.g. [method@Gtk.Frame.set_child]) instead
|
the setter for the "child" property (e.g. [method@Gtk.Frame.set_child]) instead
|
||||||
of `gtk_container_add()`. Adding a child in a ui file with <child> still works.
|
of `gtk_container_add()`. Adding a child in a ui file with `<child>` still works.
|
||||||
|
|
||||||
The affected classes are:
|
The affected classes are:
|
||||||
|
|
||||||
@@ -766,7 +790,7 @@ expand flags) and [vfunc@Gtk.Widget.get_request_mode] (if you want your
|
|||||||
container to support height-for-width).
|
container to support height-for-width).
|
||||||
|
|
||||||
You may also want to implement the [iface@Gtk.Buildable] interface, to support
|
You may also want to implement the [iface@Gtk.Buildable] interface, to support
|
||||||
adding children with <child> in ui files.
|
adding children with `<child>` in ui files.
|
||||||
|
|
||||||
### Adapt to GtkContainer removal
|
### Adapt to GtkContainer removal
|
||||||
|
|
||||||
@@ -777,7 +801,7 @@ and have class-specific add() and remove() functions.
|
|||||||
The most noticeable change is the use of [method@Gtk.Box.append] or [method@Gtk.Box.prepend]
|
The most noticeable change is the use of [method@Gtk.Box.append] or [method@Gtk.Box.prepend]
|
||||||
instead of `gtk_container_add()` for adding children to `GtkBox`, and the change
|
instead of `gtk_container_add()` for adding children to `GtkBox`, and the change
|
||||||
to use container-specific remove functions, such as [method@Gtk.Stack.remove] instead
|
to use container-specific remove functions, such as [method@Gtk.Stack.remove] instead
|
||||||
of `gtk_container_remove()`. Adding a child in a ui file with <child> still works.
|
of `gtk_container_remove()`. Adding a child in a ui file with `<child>` still works.
|
||||||
|
|
||||||
The affected classes are:
|
The affected classes are:
|
||||||
|
|
||||||
@@ -804,6 +828,11 @@ by a layout manager (if they are layout-related), or handled in some
|
|||||||
other way. One possibility is to use child meta objects, as seen with
|
other way. One possibility is to use child meta objects, as seen with
|
||||||
[class@Gtk.AssistantPage], [class@Gtk.StackPage] and the like.
|
[class@Gtk.AssistantPage], [class@Gtk.StackPage] and the like.
|
||||||
|
|
||||||
|
If you used to define child properties with `<packing>` in ui files, you have
|
||||||
|
to switch to using `<layout>` for the corresponding layout properties.
|
||||||
|
`gtk4-builder-tool` can help with this conversion, with the `--3to4` option
|
||||||
|
of the `simplify` command.
|
||||||
|
|
||||||
The replacements for gtk_container_add() are:
|
The replacements for gtk_container_add() are:
|
||||||
|
|
||||||
| Widget | Replacement |
|
| Widget | Replacement |
|
||||||
@@ -1330,3 +1359,4 @@ of tree models, and widgets instead of cell renderers.
|
|||||||
|
|
||||||
To learn more about the new list widgets, you can read the [List Widget
|
To learn more about the new list widgets, you can read the [List Widget
|
||||||
Overview](#ListWidget).
|
Overview](#ListWidget).
|
||||||
|
|
||||||
|
|||||||
+61
-19
@@ -197,6 +197,17 @@ text_buffer_changed_cb (GtkTextBuffer *buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fullscreen_changed (GObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
if (gtk_window_is_fullscreen (GTK_WINDOW (object)))
|
||||||
|
gtk_button_set_icon_name (GTK_BUTTON (user_data), "view-restore-symbolic");
|
||||||
|
else
|
||||||
|
gtk_button_set_icon_name (GTK_BUTTON (user_data), "view-fullscreen-symbolic");
|
||||||
|
}
|
||||||
|
|
||||||
static GActionEntry win_entries[] = {
|
static GActionEntry win_entries[] = {
|
||||||
{ "copy", window_copy, NULL, NULL, NULL },
|
{ "copy", window_copy, NULL, NULL, NULL },
|
||||||
{ "paste", window_paste, NULL, NULL, NULL },
|
{ "paste", window_paste, NULL, NULL, NULL },
|
||||||
@@ -214,17 +225,18 @@ new_window (GApplication *app,
|
|||||||
GtkWidget *window, *grid, *scrolled, *view;
|
GtkWidget *window, *grid, *scrolled, *view;
|
||||||
GtkWidget *toolbar;
|
GtkWidget *toolbar;
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
GtkWidget *sw, *box, *label;
|
|
||||||
|
|
||||||
window = gtk_application_window_new (GTK_APPLICATION (app));
|
window = gtk_application_window_new (GTK_APPLICATION (app));
|
||||||
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (window), win_entries, G_N_ELEMENTS (win_entries), window);
|
g_action_map_add_action_entries (G_ACTION_MAP (window), win_entries, G_N_ELEMENTS (win_entries), window);
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Bloatpad");
|
gtk_window_set_title (GTK_WINDOW (window), "Bloatpad");
|
||||||
|
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), TRUE);
|
||||||
|
|
||||||
grid = gtk_grid_new ();
|
grid = gtk_grid_new ();
|
||||||
gtk_window_set_child (GTK_WINDOW (window), grid);
|
gtk_window_set_child (GTK_WINDOW (window), grid);
|
||||||
|
|
||||||
toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
gtk_widget_add_css_class (toolbar, "toolbar");
|
||||||
button = gtk_toggle_button_new ();
|
button = gtk_toggle_button_new ();
|
||||||
gtk_button_set_icon_name (GTK_BUTTON (button), "format-justify-left");
|
gtk_button_set_icon_name (GTK_BUTTON (button), "format-justify-left");
|
||||||
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::left");
|
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::left");
|
||||||
@@ -240,21 +252,18 @@ new_window (GApplication *app,
|
|||||||
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::right");
|
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::right");
|
||||||
gtk_box_append (GTK_BOX (toolbar), button);
|
gtk_box_append (GTK_BOX (toolbar), button);
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
button = gtk_toggle_button_new ();
|
||||||
gtk_widget_set_halign (box, GTK_ALIGN_END);
|
gtk_button_set_icon_name (GTK_BUTTON (button), "view-fullscreen-symbolic");
|
||||||
label = gtk_label_new ("Fullscreen:");
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.fullscreen");
|
||||||
gtk_box_append (GTK_BOX (box), label);
|
gtk_box_append (GTK_BOX (toolbar), button);
|
||||||
sw = gtk_switch_new ();
|
g_signal_connect (window, "notify::fullscreened", G_CALLBACK (fullscreen_changed), button);
|
||||||
gtk_widget_set_valign (sw, GTK_ALIGN_CENTER);
|
|
||||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (sw), "win.fullscreen");
|
|
||||||
gtk_box_append (GTK_BOX (box), sw);
|
|
||||||
gtk_box_append (GTK_BOX (toolbar), box);
|
|
||||||
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
|
gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
|
||||||
|
|
||||||
scrolled = gtk_scrolled_window_new ();
|
scrolled = gtk_scrolled_window_new ();
|
||||||
gtk_widget_set_hexpand (scrolled, TRUE);
|
gtk_widget_set_hexpand (scrolled, TRUE);
|
||||||
gtk_widget_set_vexpand (scrolled, TRUE);
|
gtk_widget_set_vexpand (scrolled, TRUE);
|
||||||
|
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (scrolled), TRUE);
|
||||||
view = gtk_text_view_new ();
|
view = gtk_text_view_new ();
|
||||||
|
|
||||||
g_object_set_data ((GObject*)window, "bloatpad-text", view);
|
g_object_set_data ((GObject*)window, "bloatpad-text", view);
|
||||||
@@ -344,6 +353,7 @@ static void
|
|||||||
combo_changed (GtkComboBox *combo,
|
combo_changed (GtkComboBox *combo,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
GtkDialog *dialog = user_data;
|
||||||
GtkEntry *entry = g_object_get_data (user_data, "entry");
|
GtkEntry *entry = g_object_get_data (user_data, "entry");
|
||||||
const char *action;
|
const char *action;
|
||||||
char **accels;
|
char **accels;
|
||||||
@@ -359,6 +369,17 @@ combo_changed (GtkComboBox *combo,
|
|||||||
g_strfreev (accels);
|
g_strfreev (accels);
|
||||||
|
|
||||||
gtk_editable_set_text (GTK_EDITABLE (entry), str);
|
gtk_editable_set_text (GTK_EDITABLE (entry), str);
|
||||||
|
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
entry_changed (GtkEntry *entry,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkDialog *dialog = user_data;
|
||||||
|
|
||||||
|
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -372,7 +393,7 @@ response (GtkDialog *dialog,
|
|||||||
const char *str;
|
const char *str;
|
||||||
char **accels;
|
char **accels;
|
||||||
|
|
||||||
if (response_id == GTK_RESPONSE_CLOSE)
|
if (response_id == GTK_RESPONSE_CANCEL)
|
||||||
{
|
{
|
||||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||||
return;
|
return;
|
||||||
@@ -388,6 +409,8 @@ response (GtkDialog *dialog,
|
|||||||
|
|
||||||
gtk_application_set_accels_for_action (gtk_window_get_application (user_data), action, (const char **) accels);
|
gtk_application_set_accels_for_action (gtk_window_get_application (user_data), action, (const char **) accels);
|
||||||
g_strfreev (accels);
|
g_strfreev (accels);
|
||||||
|
|
||||||
|
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_APPLY, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -402,22 +425,41 @@ edit_accels (GSimpleAction *action,
|
|||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dialog = gtk_dialog_new ();
|
dialog = gtk_dialog_new_with_buttons ("Accelerators",
|
||||||
|
NULL,
|
||||||
|
GTK_DIALOG_USE_HEADER_BAR,
|
||||||
|
"Close", GTK_RESPONSE_CANCEL,
|
||||||
|
"Set", GTK_RESPONSE_APPLY,
|
||||||
|
NULL);
|
||||||
|
|
||||||
gtk_window_set_application (GTK_WINDOW (dialog), app);
|
gtk_window_set_application (GTK_WINDOW (dialog), app);
|
||||||
actions = gtk_application_list_action_descriptions (app);
|
actions = gtk_application_list_action_descriptions (app);
|
||||||
|
|
||||||
combo = gtk_combo_box_text_new ();
|
combo = gtk_combo_box_text_new ();
|
||||||
|
g_object_set (gtk_dialog_get_content_area (GTK_DIALOG (dialog)),
|
||||||
|
"margin-top", 10,
|
||||||
|
"margin-bottom", 10,
|
||||||
|
"margin-start", 10,
|
||||||
|
"margin-end", 10,
|
||||||
|
"spacing", 10,
|
||||||
|
NULL);
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), combo);
|
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), combo);
|
||||||
for (i = 0; actions[i]; i++)
|
for (i = 0; actions[i]; i++)
|
||||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), actions[i], actions[i]);
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), actions[i], actions[i]);
|
||||||
g_signal_connect (combo, "changed", G_CALLBACK (combo_changed), dialog);
|
g_signal_connect (combo, "changed", G_CALLBACK (combo_changed), dialog);
|
||||||
|
|
||||||
entry = gtk_entry_new ();
|
entry = gtk_entry_new ();
|
||||||
|
gtk_widget_set_hexpand (entry, TRUE);
|
||||||
|
g_signal_connect (entry, "notify::text", G_CALLBACK (entry_changed), dialog);
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), entry);
|
gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), entry);
|
||||||
gtk_dialog_add_button (GTK_DIALOG (dialog), "Close", GTK_RESPONSE_CLOSE);
|
|
||||||
gtk_dialog_add_button (GTK_DIALOG (dialog), "Set", GTK_RESPONSE_APPLY);
|
|
||||||
g_signal_connect (dialog, "response", G_CALLBACK (response), dialog);
|
g_signal_connect (dialog, "response", G_CALLBACK (response), dialog);
|
||||||
g_object_set_data (G_OBJECT (dialog), "combo", combo);
|
g_object_set_data (G_OBJECT (dialog), "combo", combo);
|
||||||
g_object_set_data (G_OBJECT (dialog), "entry", entry);
|
g_object_set_data (G_OBJECT (dialog), "entry", entry);
|
||||||
|
|
||||||
|
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
|
||||||
|
|
||||||
gtk_widget_show (dialog);
|
gtk_widget_show (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,7 +578,7 @@ bloat_pad_startup (GApplication *application)
|
|||||||
|
|
||||||
menu = gtk_application_get_menu_by_id (GTK_APPLICATION (application), "icon-menu");
|
menu = gtk_application_get_menu_by_id (GTK_APPLICATION (application), "icon-menu");
|
||||||
|
|
||||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/gtk-select-color.png");
|
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/insert-image.png");
|
||||||
icon = g_file_icon_new (file);
|
icon = g_file_icon_new (file);
|
||||||
item = g_menu_item_new ("File Icon", NULL);
|
item = g_menu_item_new ("File Icon", NULL);
|
||||||
g_menu_item_set_icon (item, icon);
|
g_menu_item_set_icon (item, icon);
|
||||||
@@ -552,7 +594,7 @@ bloat_pad_startup (GApplication *application)
|
|||||||
g_object_unref (item);
|
g_object_unref (item);
|
||||||
g_object_unref (icon);
|
g_object_unref (icon);
|
||||||
|
|
||||||
bytes = g_resources_lookup_data ("/org/gtk/libgtk/icons/16x16/actions/gtk-select-font.png", 0, NULL);
|
bytes = g_resources_lookup_data ("/org/gtk/libgtk/icons/16x16/actions/media-eject.png", 0, NULL);
|
||||||
icon = g_bytes_icon_new (bytes);
|
icon = g_bytes_icon_new (bytes);
|
||||||
item = g_menu_item_new ("Bytes Icon", NULL);
|
item = g_menu_item_new ("Bytes Icon", NULL);
|
||||||
g_menu_item_set_icon (item, icon);
|
g_menu_item_set_icon (item, icon);
|
||||||
@@ -561,19 +603,19 @@ bloat_pad_startup (GApplication *application)
|
|||||||
g_object_unref (icon);
|
g_object_unref (icon);
|
||||||
g_bytes_unref (bytes);
|
g_bytes_unref (bytes);
|
||||||
|
|
||||||
icon = G_ICON (gdk_pixbuf_new_from_resource ("/org/gtk/libgtk/icons/16x16/actions/gtk-preferences.png", NULL));
|
icon = G_ICON (gdk_pixbuf_new_from_resource ("/org/gtk/libgtk/icons/16x16/actions/folder-new.png", NULL));
|
||||||
item = g_menu_item_new ("Pixbuf", NULL);
|
item = g_menu_item_new ("Pixbuf", NULL);
|
||||||
g_menu_item_set_icon (item, icon);
|
g_menu_item_set_icon (item, icon);
|
||||||
g_menu_append_item (menu, item);
|
g_menu_append_item (menu, item);
|
||||||
g_object_unref (item);
|
g_object_unref (item);
|
||||||
g_object_unref (icon);
|
g_object_unref (icon);
|
||||||
|
|
||||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/gtk-page-setup.png");
|
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/bookmark-new.png");
|
||||||
icon = g_file_icon_new (file);
|
icon = g_file_icon_new (file);
|
||||||
emblem = g_emblem_new (icon);
|
emblem = g_emblem_new (icon);
|
||||||
g_object_unref (icon);
|
g_object_unref (icon);
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/gtk-orientation-reverse-portrait.png");
|
file = g_file_new_for_uri ("resource:///org/gtk/libgtk/icons/16x16/actions/dialog-warning.png");
|
||||||
icon2 = g_file_icon_new (file);
|
icon2 = g_file_icon_new (file);
|
||||||
icon = g_emblemed_icon_new (icon2, emblem);
|
icon = g_emblemed_icon_new (icon2, emblem);
|
||||||
item = g_menu_item_new ("Emblemed Icon", NULL);
|
item = g_menu_item_new ("Emblemed Icon", NULL);
|
||||||
|
|||||||
@@ -4,5 +4,10 @@
|
|||||||
<gresource prefix="/org/gtk/bloatpad">
|
<gresource prefix="/org/gtk/bloatpad">
|
||||||
<file preprocess="xml-stripblanks">gtk/menus.ui</file>
|
<file preprocess="xml-stripblanks">gtk/menus.ui</file>
|
||||||
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
||||||
|
<file>icons/16x16/actions/format-justify-center-symbolic.symbolic.png</file>
|
||||||
|
<file>icons/16x16/actions/format-justify-left-symbolic.symbolic.png</file>
|
||||||
|
<file>icons/16x16/actions/format-justify-right-symbolic.symbolic.png</file>
|
||||||
|
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
|
||||||
|
<file>icons/16x16/actions/view-restore-symbolic.symbolic.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 119 B |
Binary file not shown.
|
After Width: | Height: | Size: 115 B |
Binary file not shown.
|
After Width: | Height: | Size: 117 B |
Binary file not shown.
|
After Width: | Height: | Size: 207 B |
Binary file not shown.
|
After Width: | Height: | Size: 204 B |
+1
-5
@@ -132,7 +132,6 @@ activate (GtkApplication *app,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *frame;
|
|
||||||
GtkWidget *drawing_area;
|
GtkWidget *drawing_area;
|
||||||
GtkGesture *drag;
|
GtkGesture *drag;
|
||||||
GtkGesture *press;
|
GtkGesture *press;
|
||||||
@@ -142,14 +141,11 @@ activate (GtkApplication *app,
|
|||||||
|
|
||||||
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
||||||
|
|
||||||
frame = gtk_frame_new (NULL);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), frame);
|
|
||||||
|
|
||||||
drawing_area = gtk_drawing_area_new ();
|
drawing_area = gtk_drawing_area_new ();
|
||||||
/* set a minimum size */
|
/* set a minimum size */
|
||||||
gtk_widget_set_size_request (drawing_area, 100, 100);
|
gtk_widget_set_size_request (drawing_area, 100, 100);
|
||||||
|
|
||||||
gtk_frame_set_child (GTK_FRAME (frame), drawing_area);
|
gtk_window_set_child (GTK_WINDOW (window), drawing_area);
|
||||||
|
|
||||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw_cb, NULL, NULL);
|
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw_cb, NULL, NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ activate (GtkApplication *app,
|
|||||||
{
|
{
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
GtkWidget *box;
|
|
||||||
|
|
||||||
window = gtk_application_window_new (app);
|
window = gtk_application_window_new (app);
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label ("Hello World");
|
button = gtk_button_new_with_label ("Hello World");
|
||||||
|
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||||
|
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||||
|
|
||||||
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
|
||||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
||||||
gtk_box_append (GTK_BOX (box), button);
|
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), button);
|
||||||
|
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
project('hello', 'c',
|
||||||
|
version: '4.3.0',
|
||||||
|
meson_version: '>= 0.50.0',
|
||||||
|
)
|
||||||
|
|
||||||
|
executable('hello',
|
||||||
|
[ 'hello-world.c' ],
|
||||||
|
dependencies: [ dependency('gtk4') ],
|
||||||
|
install: false
|
||||||
|
)
|
||||||
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([]);
|
||||||
|
|
||||||
@@ -2,7 +2,6 @@ examples = [
|
|||||||
'builder',
|
'builder',
|
||||||
'drawing',
|
'drawing',
|
||||||
'grid-packing',
|
'grid-packing',
|
||||||
'hello-world',
|
|
||||||
'plugman',
|
'plugman',
|
||||||
'search-bar',
|
'search-bar',
|
||||||
'sunny',
|
'sunny',
|
||||||
|
|||||||
Executable
+61
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env -S GI_TYPELIB_PATH=${PWD}/build/gtk:${GI_TYPELIB_PATH} LD_PRELOAD=${LD_PRELOAD}:${PWD}/build/gtk/libgtk-4.so python3
|
||||||
|
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version('Gdk', '4.0')
|
||||||
|
gi.require_version('Gtk', '4.0')
|
||||||
|
|
||||||
|
from gi.repository import Gdk
|
||||||
|
from gi.repository import Gtk
|
||||||
|
from gi.repository import Graphene
|
||||||
|
|
||||||
|
|
||||||
|
class DemoWidget(Gtk.Widget):
|
||||||
|
|
||||||
|
__gtype_name__ = "DemoWidget"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def do_measure(self, orientation, for_size: int):
|
||||||
|
# We need some space to draw
|
||||||
|
return 100, 200, -1, -1
|
||||||
|
|
||||||
|
def do_snapshot(self, snapshot):
|
||||||
|
# Draw four color squares
|
||||||
|
color = Gdk.RGBA()
|
||||||
|
rect = Graphene.Rect.alloc()
|
||||||
|
|
||||||
|
width = self.get_width() / 2
|
||||||
|
height = self.get_height() / 2
|
||||||
|
|
||||||
|
Gdk.RGBA.parse(color, "red")
|
||||||
|
rect.init(0, 0, width, height)
|
||||||
|
snapshot.append_color(color, rect)
|
||||||
|
|
||||||
|
Gdk.RGBA.parse(color, "green")
|
||||||
|
rect.init(width, 0, width, height)
|
||||||
|
snapshot.append_color(color, rect)
|
||||||
|
|
||||||
|
Gdk.RGBA.parse(color, "yellow")
|
||||||
|
rect.init(0, height, width, height)
|
||||||
|
snapshot.append_color(color, rect)
|
||||||
|
|
||||||
|
Gdk.RGBA.parse(color, "blue")
|
||||||
|
rect.init(width, height, width, height)
|
||||||
|
snapshot.append_color(color, rect)
|
||||||
|
|
||||||
|
def on_activate(app):
|
||||||
|
# Create a new window
|
||||||
|
win = Gtk.ApplicationWindow(application=app)
|
||||||
|
win.set_title("Squares")
|
||||||
|
icon = DemoWidget()
|
||||||
|
win.set_child(icon)
|
||||||
|
win.present()
|
||||||
|
|
||||||
|
# Create a new application
|
||||||
|
app = Gtk.Application(application_id='org.gtk.exampleapp')
|
||||||
|
app.connect('activate', on_activate)
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
app.run(None)
|
||||||
+2
-2
@@ -12,7 +12,7 @@ new_window (GApplication *app,
|
|||||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), TRUE);
|
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), TRUE);
|
||||||
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Sunny");
|
gtk_window_set_title (GTK_WINDOW (window), "Sunny");
|
||||||
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
|
gtk_window_set_icon_name (GTK_WINDOW (window), "weather-clear-symbolic");
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||||
@@ -78,7 +78,7 @@ show_about (GSimpleAction *action,
|
|||||||
gtk_show_about_dialog (NULL,
|
gtk_show_about_dialog (NULL,
|
||||||
"program-name", "Sunny",
|
"program-name", "Sunny",
|
||||||
"title", "About Sunny",
|
"title", "About Sunny",
|
||||||
"logo-icon-name", "sunny",
|
"logo-icon-name", "weather-clear-symbolic",
|
||||||
"comments", "A cheap Bloatpad clone.",
|
"comments", "A cheap Bloatpad clone.",
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ void gdk_broadway_display_show_keyboard (GdkBroadwayDis
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gdk_broadway_display_hide_keyboard (GdkBroadwayDisplay *display);
|
void gdk_broadway_display_hide_keyboard (GdkBroadwayDisplay *display);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_4
|
||||||
|
int gdk_broadway_display_get_surface_scale (GdkDisplay *display);
|
||||||
GDK_AVAILABLE_IN_4_4
|
GDK_AVAILABLE_IN_4_4
|
||||||
void gdk_broadway_display_set_surface_scale (GdkDisplay *display,
|
void gdk_broadway_display_set_surface_scale (GdkDisplay *display,
|
||||||
int scale);
|
int scale);
|
||||||
|
|||||||
@@ -361,6 +361,29 @@ gdk_broadway_display_set_surface_scale (GdkDisplay *display,
|
|||||||
gdk_monitor_set_scale_factor (self->monitor, scale);
|
gdk_monitor_set_scale_factor (self->monitor, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_broadway_display_get_surface_scale:
|
||||||
|
* @display: (type GdkBroadwayDisplay): the display
|
||||||
|
*
|
||||||
|
* Gets the surface scale that was previously set by the client or
|
||||||
|
* gdk_broadway_display_set_surface_scale().
|
||||||
|
*
|
||||||
|
* Returns: the scale for surfaces
|
||||||
|
*
|
||||||
|
* Since: 4.4
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
gdk_broadway_display_get_surface_scale (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
GdkBroadwayDisplay *self;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_BROADWAY_DISPLAY (display), 1);
|
||||||
|
|
||||||
|
self = GDK_BROADWAY_DISPLAY (display);
|
||||||
|
|
||||||
|
return self->scale_factor;
|
||||||
|
}
|
||||||
|
|
||||||
static GListModel *
|
static GListModel *
|
||||||
gdk_broadway_display_get_monitors (GdkDisplay *display)
|
gdk_broadway_display_get_monitors (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -127,7 +127,9 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
|||||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context" },
|
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context" },
|
||||||
{ "gl-gles", GDK_DEBUG_GL_GLES, "Use a GLES 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-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-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-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
|
||||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
|
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
|
||||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
|
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
|
||||||
@@ -330,14 +332,13 @@ gdk_display_open_default (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
*
|
* gdk_get_startup_notification_id:
|
||||||
* gdk_get_startup_notification_id
|
|
||||||
*
|
*
|
||||||
* Returns the original value of the DESKTOP_STARTUP_ID environment
|
* Returns the original value of the DESKTOP_STARTUP_ID environment
|
||||||
* variable if it was defined and valid, or %NULL otherwise.
|
* variable if it was defined and valid, or %NULL otherwise.
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (transfer none): the original value of the
|
* Returns: (nullable) (transfer none): the original value of the
|
||||||
* DESKTOP_STARTUP_ID environment variable, or %NULL.
|
* DESKTOP_STARTUP_ID environment variable
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
gdk_get_startup_notification_id (void)
|
gdk_get_startup_notification_id (void)
|
||||||
|
|||||||
+1
-1
@@ -340,7 +340,7 @@ gdk_cursor_new_from_name (const char *name,
|
|||||||
* @texture: the texture providing the pixel data
|
* @texture: the texture providing the pixel data
|
||||||
* @hotspot_x: the horizontal offset of the “hotspot” of the cursor
|
* @hotspot_x: the horizontal offset of the “hotspot” of the cursor
|
||||||
* @hotspot_y: the vertical offset of the “hotspot” of the cursor
|
* @hotspot_y: the vertical offset of the “hotspot” of the cursor
|
||||||
* @fallback: (nullable): %NULL or the `GdkCursor` to fall back to when
|
* @fallback: (nullable): the `GdkCursor` to fall back to when
|
||||||
* this one cannot be supported
|
* this one cannot be supported
|
||||||
*
|
*
|
||||||
* Creates a new cursor from a `GdkTexture`.
|
* Creates a new cursor from a `GdkTexture`.
|
||||||
|
|||||||
+6
-4
@@ -41,10 +41,12 @@ typedef enum {
|
|||||||
GDK_DEBUG_GL_LEGACY = 1 << 15,
|
GDK_DEBUG_GL_LEGACY = 1 << 15,
|
||||||
GDK_DEBUG_GL_GLES = 1 << 16,
|
GDK_DEBUG_GL_GLES = 1 << 16,
|
||||||
GDK_DEBUG_GL_DEBUG = 1 << 17,
|
GDK_DEBUG_GL_DEBUG = 1 << 17,
|
||||||
GDK_DEBUG_GL_GLX = 1 << 18,
|
GDK_DEBUG_GL_EGL = 1 << 18,
|
||||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 19,
|
GDK_DEBUG_GL_GLX = 1 << 19,
|
||||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 20,
|
GDK_DEBUG_GL_WGL = 1 << 20,
|
||||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 21
|
GDK_DEBUG_VULKAN_DISABLE = 1 << 21,
|
||||||
|
GDK_DEBUG_VULKAN_VALIDATE = 1 << 22,
|
||||||
|
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 23,
|
||||||
} GdkDebugFlags;
|
} GdkDebugFlags;
|
||||||
|
|
||||||
extern guint _gdk_debug_flags;
|
extern guint _gdk_debug_flags;
|
||||||
|
|||||||
+187
-37
@@ -77,6 +77,23 @@ enum {
|
|||||||
LAST_SIGNAL
|
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_dispose (GObject *object);
|
||||||
static void gdk_display_finalize (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 };
|
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
|
static void
|
||||||
gdk_display_get_property (GObject *object,
|
gdk_display_get_property (GObject *object,
|
||||||
@@ -119,10 +136,14 @@ gdk_display_real_make_default (GdkDisplay *display)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GdkGLContext *
|
||||||
gdk_display_real_opened (GdkDisplay *display)
|
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 *
|
static GdkSeat *
|
||||||
@@ -134,6 +155,12 @@ gdk_display_real_get_default_seat (GdkDisplay *display)
|
|||||||
return display->seats->data;
|
return display->seats->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_display_real_opened (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
_gdk_display_manager_add_display (gdk_display_manager_get (), display);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_display_class_init (GdkDisplayClass *class)
|
gdk_display_class_init (GdkDisplayClass *class)
|
||||||
{
|
{
|
||||||
@@ -143,10 +170,11 @@ gdk_display_class_init (GdkDisplayClass *class)
|
|||||||
object_class->dispose = gdk_display_dispose;
|
object_class->dispose = gdk_display_dispose;
|
||||||
object_class->get_property = gdk_display_get_property;
|
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->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->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)
|
* GdkDisplay:composited: (attributes org.gtk.Property.get=gdk_display_is_composited)
|
||||||
@@ -294,6 +322,8 @@ free_device_grabs_foreach (gpointer key,
|
|||||||
static void
|
static void
|
||||||
gdk_display_init (GdkDisplay *display)
|
gdk_display_init (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||||
|
|
||||||
display->double_click_time = 250;
|
display->double_click_time = 250;
|
||||||
display->double_click_distance = 5;
|
display->double_click_distance = 5;
|
||||||
|
|
||||||
@@ -304,22 +334,26 @@ gdk_display_init (GdkDisplay *display)
|
|||||||
|
|
||||||
g_queue_init (&display->queued_events);
|
g_queue_init (&display->queued_events);
|
||||||
|
|
||||||
display->debug_flags = _gdk_debug_flags;
|
priv->debug_flags = _gdk_debug_flags;
|
||||||
|
|
||||||
display->composited = TRUE;
|
priv->composited = TRUE;
|
||||||
display->rgba = TRUE;
|
priv->rgba = TRUE;
|
||||||
display->input_shapes = TRUE;
|
priv->input_shapes = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_display_dispose (GObject *object)
|
gdk_display_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
GdkDisplay *display = GDK_DISPLAY (object);
|
GdkDisplay *display = GDK_DISPLAY (object);
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||||
|
|
||||||
_gdk_display_manager_remove_display (gdk_display_manager_get (), display);
|
_gdk_display_manager_remove_display (gdk_display_manager_get (), display);
|
||||||
|
|
||||||
g_queue_clear (&display->queued_events);
|
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);
|
G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,11 +418,11 @@ gdk_display_is_closed (GdkDisplay *display)
|
|||||||
* gdk_display_get_event:
|
* gdk_display_get_event:
|
||||||
* @display: a `GdkDisplay`
|
* @display: a `GdkDisplay`
|
||||||
*
|
*
|
||||||
* Gets the next `GdkEvent` to be processed for @display, fetching events from the
|
* Gets the next `GdkEvent` to be processed for @display,
|
||||||
* windowing system if necessary.
|
* fetching events from the windowing system if necessary.
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (transfer full): the next `GdkEvent` to be processed,
|
* Returns: (nullable) (transfer full): the next `GdkEvent`
|
||||||
* or %NULL if no events are pending
|
* to be processed
|
||||||
*/
|
*/
|
||||||
GdkEvent *
|
GdkEvent *
|
||||||
gdk_display_get_event (GdkDisplay *display)
|
gdk_display_get_event (GdkDisplay *display)
|
||||||
@@ -998,21 +1032,25 @@ gdk_display_get_primary_clipboard (GdkDisplay *display)
|
|||||||
gboolean
|
gboolean
|
||||||
gdk_display_supports_input_shapes (GdkDisplay *display)
|
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);
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||||
|
|
||||||
return display->input_shapes;
|
return priv->input_shapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_display_set_input_shapes (GdkDisplay *display,
|
gdk_display_set_input_shapes (GdkDisplay *display,
|
||||||
gboolean input_shapes)
|
gboolean input_shapes)
|
||||||
{
|
{
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||||
|
|
||||||
if (display->input_shapes == input_shapes)
|
if (priv->input_shapes == input_shapes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
display->input_shapes = input_shapes;
|
priv->input_shapes = input_shapes;
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_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);
|
return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*< private >
|
static void
|
||||||
* gdk_display_make_gl_context_current:
|
gdk_display_init_gl (GdkDisplay *self)
|
||||||
* @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)
|
|
||||||
{
|
{
|
||||||
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
|
GdkDebugFlags
|
||||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
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
|
void
|
||||||
gdk_display_set_debug_flags (GdkDisplay *display,
|
gdk_display_set_debug_flags (GdkDisplay *display,
|
||||||
GdkDebugFlags flags)
|
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
|
gboolean
|
||||||
gdk_display_is_composited (GdkDisplay *display)
|
gdk_display_is_composited (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||||
|
|
||||||
return display->composited;
|
return priv->composited;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_display_set_composited (GdkDisplay *display,
|
gdk_display_set_composited (GdkDisplay *display,
|
||||||
gboolean composited)
|
gboolean composited)
|
||||||
{
|
{
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||||
|
|
||||||
if (display->composited == composited)
|
if (priv->composited == composited)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
display->composited = composited;
|
priv->composited = composited;
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_COMPOSITED]);
|
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_COMPOSITED]);
|
||||||
}
|
}
|
||||||
@@ -1248,21 +1394,25 @@ gdk_display_set_composited (GdkDisplay *display,
|
|||||||
gboolean
|
gboolean
|
||||||
gdk_display_is_rgba (GdkDisplay *display)
|
gdk_display_is_rgba (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||||
|
|
||||||
return display->rgba;
|
return priv->rgba;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_display_set_rgba (GdkDisplay *display,
|
gdk_display_set_rgba (GdkDisplay *display,
|
||||||
gboolean rgba)
|
gboolean rgba)
|
||||||
{
|
{
|
||||||
|
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||||
|
|
||||||
if (display->rgba == rgba)
|
if (priv->rgba == rgba)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
display->rgba = rgba;
|
priv->rgba = rgba;
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_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
|
GDK_AVAILABLE_IN_ALL
|
||||||
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
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
|
GDK_AVAILABLE_IN_ALL
|
||||||
GdkDisplay *gdk_display_get_default (void);
|
GdkDisplay *gdk_display_get_default (void);
|
||||||
|
|
||||||
|
|||||||
@@ -323,7 +323,8 @@ gdk_display_manager_get_default_display (GdkDisplayManager *manager)
|
|||||||
* Gets the default `GdkDisplay`.
|
* Gets the default `GdkDisplay`.
|
||||||
*
|
*
|
||||||
* This is a convenience function for:
|
* This is a convenience function for:
|
||||||
* `gdk_display_manager_get_default_display (gdk_display_manager_get ())`.
|
*
|
||||||
|
* gdk_display_manager_get_default_display (gdk_display_manager_get ())
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (transfer none): a `GdkDisplay`, or %NULL if
|
* Returns: (nullable) (transfer none): a `GdkDisplay`, or %NULL if
|
||||||
* there is no default display
|
* there is no default display
|
||||||
|
|||||||
@@ -102,11 +102,6 @@ struct _GdkDisplay
|
|||||||
|
|
||||||
guint vulkan_refcount;
|
guint vulkan_refcount;
|
||||||
#endif /* GDK_RENDERING_VULKAN */
|
#endif /* GDK_RENDERING_VULKAN */
|
||||||
guint rgba : 1;
|
|
||||||
guint composited : 1;
|
|
||||||
guint input_shapes : 1;
|
|
||||||
|
|
||||||
GdkDebugFlags debug_flags;
|
|
||||||
|
|
||||||
GList *seats;
|
GList *seats;
|
||||||
};
|
};
|
||||||
@@ -145,8 +140,8 @@ struct _GdkDisplayClass
|
|||||||
|
|
||||||
GdkKeymap * (*get_keymap) (GdkDisplay *display);
|
GdkKeymap * (*get_keymap) (GdkDisplay *display);
|
||||||
|
|
||||||
gboolean (*make_gl_context_current) (GdkDisplay *display,
|
GdkGLContext * (*init_gl) (GdkDisplay *display,
|
||||||
GdkGLContext *context);
|
GError **error);
|
||||||
|
|
||||||
GdkSeat * (*get_default_seat) (GdkDisplay *display);
|
GdkSeat * (*get_default_seat) (GdkDisplay *display);
|
||||||
|
|
||||||
@@ -211,8 +206,7 @@ GdkSurface * gdk_display_create_surface (GdkDisplay *display
|
|||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
|
||||||
gboolean gdk_display_make_gl_context_current (GdkDisplay *display,
|
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
|
||||||
GdkGLContext *context);
|
|
||||||
|
|
||||||
void gdk_display_set_rgba (GdkDisplay *display,
|
void gdk_display_set_rgba (GdkDisplay *display,
|
||||||
gboolean rgba);
|
gboolean rgba);
|
||||||
|
|||||||
+28
-4
@@ -43,6 +43,7 @@
|
|||||||
typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate;
|
typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate;
|
||||||
|
|
||||||
struct _GdkDrawContextPrivate {
|
struct _GdkDrawContextPrivate {
|
||||||
|
GdkDisplay *display;
|
||||||
GdkSurface *surface;
|
GdkSurface *surface;
|
||||||
|
|
||||||
cairo_region_t *frame_region;
|
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);
|
priv->surface->draw_contexts = g_slist_remove (priv->surface->draw_contexts, context);
|
||||||
g_clear_object (&priv->surface);
|
g_clear_object (&priv->surface);
|
||||||
}
|
}
|
||||||
|
g_clear_object (&priv->display);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_draw_context_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (gdk_draw_context_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
@@ -92,10 +94,31 @@ gdk_draw_context_set_property (GObject *gobject,
|
|||||||
|
|
||||||
switch (prop_id)
|
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:
|
case PROP_SURFACE:
|
||||||
priv->surface = g_value_dup_object (value);
|
priv->surface = g_value_dup_object (value);
|
||||||
g_assert (priv->surface != NULL);
|
if (priv->surface)
|
||||||
priv->surface->draw_contexts = g_slist_prepend (priv->surface->draw_contexts, context);
|
{
|
||||||
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -148,7 +171,8 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
|||||||
P_("Display"),
|
P_("Display"),
|
||||||
P_("The GDK display used to create the context"),
|
P_("The GDK display used to create the context"),
|
||||||
GDK_TYPE_DISPLAY,
|
GDK_TYPE_DISPLAY,
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
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);
|
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
|
||||||
|
|
||||||
return priv->surface ? gdk_surface_get_display (priv->surface) : NULL;
|
return priv->display;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+6
-3
@@ -294,8 +294,11 @@ gdk_drop_finalize (GObject *object)
|
|||||||
|
|
||||||
/* someone forgot to send a LEAVE signal */
|
/* someone forgot to send a LEAVE signal */
|
||||||
g_warn_if_fail (!priv->entered);
|
g_warn_if_fail (!priv->entered);
|
||||||
|
|
||||||
/* Should we emit finish() here if necessary?
|
/* Should we emit finish() here if necessary?
|
||||||
* For now that's the backends' job */
|
* For now that's the backends' job
|
||||||
|
*/
|
||||||
|
g_warn_if_fail (priv->state != GDK_DROP_STATE_DROPPING);
|
||||||
|
|
||||||
g_clear_object (&priv->device);
|
g_clear_object (&priv->device);
|
||||||
g_clear_object (&priv->drag);
|
g_clear_object (&priv->drag);
|
||||||
@@ -571,7 +574,7 @@ gdk_drop_get_drag (GdkDrop *self)
|
|||||||
* the ones provided by [method@Gdk.Drop.get_actions]. Those actions may
|
* the ones provided by [method@Gdk.Drop.get_actions]. Those actions may
|
||||||
* change in the future, even depending on the actions you provide here.
|
* change in the future, even depending on the actions you provide here.
|
||||||
*
|
*
|
||||||
* The @preferred action is a hint to the drag'n'drop mechanism about which
|
* The @preferred action is a hint to the drag-and-drop mechanism about which
|
||||||
* action to use when multiple actions are possible.
|
* action to use when multiple actions are possible.
|
||||||
*
|
*
|
||||||
* This function should be called by drag destinations in response to
|
* This function should be called by drag destinations in response to
|
||||||
@@ -862,7 +865,7 @@ gdk_drop_read_value_internal (GdkDrop *self,
|
|||||||
* then call [method@Gdk.Drop.read_value_finish] to get the resulting
|
* then call [method@Gdk.Drop.read_value_finish] to get the resulting
|
||||||
* `GValue`.
|
* `GValue`.
|
||||||
*
|
*
|
||||||
* For local drag'n'drop operations that are available in the given
|
* For local drag-and-drop operations that are available in the given
|
||||||
* `GType`, the value will be copied directly. Otherwise, GDK will
|
* `GType`, the value will be copied directly. Otherwise, GDK will
|
||||||
* try to use [func@Gdk.content_deserialize_async] to convert the data.
|
* try to use [func@Gdk.content_deserialize_async] to convert the data.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-3
@@ -481,11 +481,11 @@ _gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
|
|||||||
* for the current frame or a recent frame.
|
* for the current frame or a recent frame.
|
||||||
*
|
*
|
||||||
* The `GdkFrameTimings` object may not yet be complete: see
|
* The `GdkFrameTimings` object may not yet be complete: see
|
||||||
* [method@Gdk.FrameTimings.get_complete].
|
* [method@Gdk.FrameTimings.get_complete] and
|
||||||
|
* [method@Gdk.FrameClock.get_history_start].
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (transfer none): the `GdkFrameTimings` object
|
* Returns: (nullable) (transfer none): the `GdkFrameTimings` object
|
||||||
* for the specified frame, or %NULL if it is not available. See
|
* for the specified frame, or %NULL if it is not available
|
||||||
* [method@Gdk.FrameClock.get_history_start].
|
|
||||||
*/
|
*/
|
||||||
GdkFrameTimings *
|
GdkFrameTimings *
|
||||||
gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
|
gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
|
||||||
|
|||||||
+127
-52
@@ -89,8 +89,6 @@
|
|||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GdkGLContext *shared_context;
|
|
||||||
|
|
||||||
int major;
|
int major;
|
||||||
int minor;
|
int minor;
|
||||||
int gl_version;
|
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)
|
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
|
static void
|
||||||
gdk_gl_context_clear_old_updated_area (GdkGLContext *context)
|
gdk_gl_context_clear_old_updated_area (GdkGLContext *context)
|
||||||
@@ -144,17 +163,14 @@ static void
|
|||||||
gdk_gl_context_dispose (GObject *gobject)
|
gdk_gl_context_dispose (GObject *gobject)
|
||||||
{
|
{
|
||||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
MaskedContext *current;
|
||||||
GdkGLContext *current;
|
|
||||||
|
|
||||||
gdk_gl_context_clear_old_updated_area (context);
|
gdk_gl_context_clear_old_updated_area (context);
|
||||||
|
|
||||||
current = g_private_get (&thread_current_context);
|
current = g_private_get (&thread_current_context);
|
||||||
if (current == context)
|
if (unmask_context (current) == context)
|
||||||
g_private_replace (&thread_current_context, NULL);
|
g_private_replace (&thread_current_context, NULL);
|
||||||
|
|
||||||
g_clear_object (&priv->shared_context);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_gl_context_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (gdk_gl_context_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,17 +190,10 @@ gdk_gl_context_set_property (GObject *gobject,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_SHARED_CONTEXT:
|
case PROP_SHARED_CONTEXT:
|
||||||
{
|
g_assert (g_value_get_object (value) == NULL);
|
||||||
GdkGLContext *context = g_value_get_object (value);
|
|
||||||
|
|
||||||
if (context != NULL)
|
|
||||||
priv->shared_context = g_object_ref (context);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -198,12 +207,10 @@ gdk_gl_context_get_property (GObject *gobject,
|
|||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_SHARED_CONTEXT:
|
case PROP_SHARED_CONTEXT:
|
||||||
g_value_set_object (value, priv->shared_context);
|
g_value_set_object (value, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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
|
static void
|
||||||
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||||
cairo_region_t *region)
|
cairo_region_t *region)
|
||||||
{
|
{
|
||||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||||
GdkSurface *surface;
|
GdkSurface *surface;
|
||||||
GdkGLContext *shared;
|
|
||||||
cairo_region_t *damage;
|
cairo_region_t *damage;
|
||||||
int ww, wh;
|
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);
|
damage = GDK_GL_CONTEXT_GET_CLASS (context)->get_damage (context);
|
||||||
|
|
||||||
if (context->old_updated_area[1])
|
if (context->old_updated_area[1])
|
||||||
@@ -379,15 +390,6 @@ static void
|
|||||||
gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||||
cairo_region_t *painted)
|
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
|
static void
|
||||||
@@ -406,6 +408,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
|||||||
|
|
||||||
klass->realize = gdk_gl_context_real_realize;
|
klass->realize = gdk_gl_context_real_realize;
|
||||||
klass->get_damage = gdk_gl_context_real_get_damage;
|
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->begin_frame = gdk_gl_context_real_begin_frame;
|
||||||
draw_context_class->end_frame = gdk_gl_context_real_end_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)
|
* 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] =
|
obj_pspecs[PROP_SHARED_CONTEXT] =
|
||||||
g_param_spec_object ("shared-context",
|
g_param_spec_object ("shared-context",
|
||||||
@@ -423,7 +432,8 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
|||||||
GDK_TYPE_GL_CONTEXT,
|
GDK_TYPE_GL_CONTEXT,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
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->set_property = gdk_gl_context_set_property;
|
||||||
gobject_class->get_property = gdk_gl_context_get_property;
|
gobject_class->get_property = gdk_gl_context_get_property;
|
||||||
@@ -441,6 +451,21 @@ gdk_gl_context_init (GdkGLContext *self)
|
|||||||
priv->use_es = -1;
|
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 *
|
GdkGLContextPaintData *
|
||||||
gdk_gl_context_get_paint_data (GdkGLContext *context)
|
gdk_gl_context_get_paint_data (GdkGLContext *context)
|
||||||
{
|
{
|
||||||
@@ -812,6 +837,42 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
|||||||
priv->is_legacy = !!is_legacy;
|
priv->is_legacy = !!is_legacy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_gl_context_is_shared:
|
||||||
|
* @self: a `GdkGLContext`
|
||||||
|
* @other: the `GdkGLContext` that should be compatible with @self
|
||||||
|
*
|
||||||
|
* Checks if the two GL contexts can share resources.
|
||||||
|
*
|
||||||
|
* When they can, the texture IDs from @other can be used in @self. This
|
||||||
|
* is particularly useful when passing `GdkGLTexture` objects between
|
||||||
|
* different contexts.
|
||||||
|
*
|
||||||
|
* Contexts created for the same display with the same properties will
|
||||||
|
* always be compatible, even if they are created for different surfaces.
|
||||||
|
* For other contexts it depends on the GL backend.
|
||||||
|
*
|
||||||
|
* Both contexts must be realized for this check to succeed. If either one
|
||||||
|
* is not, this function will return %FALSE.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the two GL contexts are compatible.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gdk_gl_context_is_shared (GdkGLContext *self,
|
||||||
|
GdkGLContext *other)
|
||||||
|
{
|
||||||
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||||
|
GdkGLContextPrivate *priv_other = gdk_gl_context_get_instance_private (other);
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||||
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (other), FALSE);
|
||||||
|
|
||||||
|
if (!priv->realized || !priv_other->realized)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return GDK_GL_CONTEXT_GET_CLASS (self)->is_shared (self, other);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_gl_context_set_use_es:
|
* gdk_gl_context_set_use_es:
|
||||||
* @context: a `GdkGLContext`
|
* @context: a `GdkGLContext`
|
||||||
@@ -1092,12 +1153,16 @@ void
|
|||||||
gdk_gl_context_make_current (GdkGLContext *context)
|
gdk_gl_context_make_current (GdkGLContext *context)
|
||||||
{
|
{
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (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));
|
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);
|
current = g_private_get (&thread_current_context);
|
||||||
if (current == context)
|
if (current == masked_context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
||||||
@@ -1114,11 +1179,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));
|
g_warning ("gdk_gl_context_make_current() failed");
|
||||||
gdk_gl_context_check_extensions (context);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_object_ref (context);
|
||||||
|
g_private_replace (&thread_current_context, masked_context);
|
||||||
|
gdk_gl_context_check_extensions (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1157,18 +1226,22 @@ gdk_gl_context_get_surface (GdkGLContext *context)
|
|||||||
* gdk_gl_context_get_shared_context: (attributes org.gtk.Method.get_property=shared-context)
|
* gdk_gl_context_get_shared_context: (attributes org.gtk.Method.get_property=shared-context)
|
||||||
* @context: a `GdkGLContext`
|
* @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 *
|
GdkGLContext *
|
||||||
gdk_gl_context_get_shared_context (GdkGLContext *context)
|
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);
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
||||||
|
|
||||||
return priv->shared_context;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1208,12 +1281,14 @@ gdk_gl_context_get_version (GdkGLContext *context,
|
|||||||
void
|
void
|
||||||
gdk_gl_context_clear_current (void)
|
gdk_gl_context_clear_current (void)
|
||||||
{
|
{
|
||||||
GdkGLContext *current;
|
MaskedContext *current;
|
||||||
|
|
||||||
current = g_private_get (&thread_current_context);
|
current = g_private_get (&thread_current_context);
|
||||||
if (current != NULL)
|
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);
|
g_private_replace (&thread_current_context, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1228,11 +1303,11 @@ gdk_gl_context_clear_current (void)
|
|||||||
GdkGLContext *
|
GdkGLContext *
|
||||||
gdk_gl_context_get_current (void)
|
gdk_gl_context_get_current (void)
|
||||||
{
|
{
|
||||||
GdkGLContext *current;
|
MaskedContext *current;
|
||||||
|
|
||||||
current = g_private_get (&thread_current_context);
|
current = g_private_get (&thread_current_context);
|
||||||
|
|
||||||
return current;
|
return unmask_context (current);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|||||||
+5
-2
@@ -45,8 +45,8 @@ GType gdk_gl_context_get_type (void) G_GNUC_CONST;
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GdkDisplay * gdk_gl_context_get_display (GdkGLContext *context);
|
GdkDisplay * gdk_gl_context_get_display (GdkGLContext *context);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GdkSurface * gdk_gl_context_get_surface (GdkGLContext *context);
|
GdkSurface * gdk_gl_context_get_surface (GdkGLContext *context);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_DEPRECATED_IN_4_4_FOR(gdk_gl_context_is_shared)
|
||||||
GdkGLContext * gdk_gl_context_get_shared_context (GdkGLContext *context);
|
GdkGLContext * gdk_gl_context_get_shared_context (GdkGLContext *context);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gdk_gl_context_get_version (GdkGLContext *context,
|
void gdk_gl_context_get_version (GdkGLContext *context,
|
||||||
@@ -54,6 +54,9 @@ void gdk_gl_context_get_version (GdkGLContext *
|
|||||||
int *minor);
|
int *minor);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
gboolean gdk_gl_context_is_legacy (GdkGLContext *context);
|
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
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gdk_gl_context_set_required_version (GdkGLContext *context,
|
void gdk_gl_context_set_required_version (GdkGLContext *context,
|
||||||
|
|||||||
@@ -27,6 +27,13 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
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_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_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))
|
#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;
|
GdkDrawContextClass parent_class;
|
||||||
|
|
||||||
gboolean (* realize) (GdkGLContext *context,
|
gboolean (* realize) (GdkGLContext *context,
|
||||||
GError **error);
|
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 {
|
typedef struct {
|
||||||
@@ -73,6 +86,8 @@ typedef struct {
|
|||||||
guint use_es : 1;
|
guint use_es : 1;
|
||||||
} GdkGLContextPaintData;
|
} GdkGLContextPaintData;
|
||||||
|
|
||||||
|
GdkGLContext * gdk_gl_context_new_for_surface (GdkSurface *surface);
|
||||||
|
|
||||||
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||||
gboolean is_legacy);
|
gboolean is_legacy);
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ G_BEGIN_DECLS
|
|||||||
* CAIRO_FORMAT_ARGB32 is represented by different `GdkMemoryFormats`
|
* CAIRO_FORMAT_ARGB32 is represented by different `GdkMemoryFormats`
|
||||||
* on architectures with different endiannesses.
|
* on architectures with different endiannesses.
|
||||||
*
|
*
|
||||||
* Its naming is modelled after VkFormat (see
|
* Its naming is modelled after
|
||||||
* https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkFormat
|
* [VkFormat](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkFormat)
|
||||||
* for details).
|
* for details).
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
+10
-80
@@ -1065,87 +1065,23 @@ gdk_surface_get_mapped (GdkSurface *surface)
|
|||||||
return GDK_SURFACE_IS_MAPPED (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 *
|
GdkGLContext *
|
||||||
gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GError *internal_error = NULL;
|
if (!gdk_display_prepare_gl (surface->display, error))
|
||||||
|
return NULL;
|
||||||
if (GDK_DISPLAY_DEBUG_CHECK (surface->display, GL_DISABLE))
|
|
||||||
{
|
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
|
||||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
|
||||||
_("GL support disabled via GDK_DEBUG"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surface->gl_paint_context == NULL)
|
if (surface->gl_paint_context == NULL)
|
||||||
{
|
{
|
||||||
GdkSurfaceClass *class = GDK_SURFACE_GET_CLASS (surface);
|
surface->gl_paint_context = gdk_surface_create_gl_context (surface, error);
|
||||||
|
if (surface->gl_paint_context == NULL)
|
||||||
if (class->create_gl_context == NULL)
|
return NULL;
|
||||||
{
|
|
||||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
|
||||||
_("The current backend does not support OpenGL"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->gl_paint_context =
|
|
||||||
class->create_gl_context (surface, TRUE, NULL, &internal_error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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);
|
||||||
g_clear_object (&(surface->gl_paint_context));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gdk_gl_context_realize (surface->gl_paint_context, &internal_error);
|
|
||||||
if (internal_error != NULL)
|
|
||||||
{
|
|
||||||
g_propagate_error (error, internal_error);
|
|
||||||
g_clear_object (&(surface->gl_paint_context));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1170,19 +1106,13 @@ GdkGLContext *
|
|||||||
gdk_surface_create_gl_context (GdkSurface *surface,
|
gdk_surface_create_gl_context (GdkSurface *surface,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GdkGLContext *paint_context;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
paint_context = gdk_surface_get_paint_gl_context (surface, error);
|
if (!gdk_display_prepare_gl (surface->display, error))
|
||||||
if (paint_context == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface,
|
return gdk_gl_context_new_for_surface (surface);
|
||||||
FALSE,
|
|
||||||
paint_context,
|
|
||||||
error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -160,10 +160,6 @@ struct _GdkSurfaceClass
|
|||||||
|
|
||||||
void (* set_opaque_region) (GdkSurface *surface,
|
void (* set_opaque_region) (GdkSurface *surface,
|
||||||
cairo_region_t *region);
|
cairo_region_t *region);
|
||||||
GdkGLContext *(*create_gl_context) (GdkSurface *surface,
|
|
||||||
gboolean attached,
|
|
||||||
GdkGLContext *share,
|
|
||||||
GError **error);
|
|
||||||
void (* request_layout) (GdkSurface *surface);
|
void (* request_layout) (GdkSurface *surface);
|
||||||
gboolean (* compute_size) (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,
|
GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||||
GError **error);
|
GError **error);
|
||||||
GdkGLContext * gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
|
|
||||||
|
|
||||||
gboolean gdk_surface_handle_event (GdkEvent *event);
|
gboolean gdk_surface_handle_event (GdkEvent *event);
|
||||||
GdkSeat * gdk_surface_get_seat_from_event (GdkSurface *surface,
|
GdkSeat * gdk_surface_get_seat_from_event (GdkSurface *surface,
|
||||||
|
|||||||
+1
-1
@@ -533,7 +533,7 @@ gdk_texture_get_render_data (GdkTexture *self,
|
|||||||
/**
|
/**
|
||||||
* gdk_texture_save_to_png:
|
* gdk_texture_save_to_png:
|
||||||
* @texture: a `GdkTexture`
|
* @texture: a `GdkTexture`
|
||||||
* @filename: the filename to store to
|
* @filename: (type filename): the filename to store to
|
||||||
*
|
*
|
||||||
* Store the given @texture to the @filename as a PNG file.
|
* Store the given @texture to the @filename as a PNG file.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -28,7 +28,9 @@
|
|||||||
#import "GdkMacosGLView.h"
|
#import "GdkMacosGLView.h"
|
||||||
#import "GdkMacosWindow.h"
|
#import "GdkMacosWindow.h"
|
||||||
|
|
||||||
|
#include "gdkmacosclipboard-private.h"
|
||||||
#include "gdkmacosdisplay-private.h"
|
#include "gdkmacosdisplay-private.h"
|
||||||
|
#include "gdkmacosdrop-private.h"
|
||||||
#include "gdkmacosmonitor-private.h"
|
#include "gdkmacosmonitor-private.h"
|
||||||
#include "gdkmacossurface-private.h"
|
#include "gdkmacossurface-private.h"
|
||||||
#include "gdkmacospopupsurface-private.h"
|
#include "gdkmacospopupsurface-private.h"
|
||||||
@@ -287,6 +289,9 @@ typedef NSString *CALayerContentsGravity;
|
|||||||
[self setContentView:view];
|
[self setContentView:view];
|
||||||
[view release];
|
[view release];
|
||||||
|
|
||||||
|
/* TODO: We might want to make this more extensible at some point */
|
||||||
|
_gdk_macos_clipboard_register_drag_types (self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,25 +602,86 @@ typedef NSString *CALayerContentsGravity;
|
|||||||
|
|
||||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
return NSDragOperationNone;
|
NSPoint location = [sender draggingLocation];
|
||||||
|
NSDragOperation ret;
|
||||||
|
GdkMacosDrop *drop;
|
||||||
|
|
||||||
|
if (!(drop = _gdk_macos_drop_new ([self gdkSurface], sender)))
|
||||||
|
return NSDragOperationNone;
|
||||||
|
|
||||||
|
_gdk_macos_display_set_drop ([self gdkDisplay],
|
||||||
|
[sender draggingSequenceNumber],
|
||||||
|
GDK_DROP (drop));
|
||||||
|
|
||||||
|
gdk_drop_emit_enter_event (GDK_DROP (drop),
|
||||||
|
TRUE,
|
||||||
|
location.x,
|
||||||
|
GDK_SURFACE (gdk_surface)->height - location.y,
|
||||||
|
GDK_CURRENT_TIME);
|
||||||
|
|
||||||
|
ret = _gdk_macos_drop_operation (drop);
|
||||||
|
|
||||||
|
g_object_unref (drop);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)draggingEnded:(id <NSDraggingInfo>)sender
|
-(void)draggingEnded:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
|
_gdk_macos_display_set_drop ([self gdkDisplay], [sender draggingSequenceNumber], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)draggingExited:(id <NSDraggingInfo>)sender
|
-(void)draggingExited:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
|
NSInteger sequence_number = [sender draggingSequenceNumber];
|
||||||
|
GdkDrop *drop = _gdk_macos_display_find_drop ([self gdkDisplay], sequence_number);
|
||||||
|
|
||||||
|
if (drop != NULL)
|
||||||
|
gdk_drop_emit_leave_event (drop, TRUE, GDK_CURRENT_TIME);
|
||||||
|
|
||||||
|
_gdk_macos_display_set_drop ([self gdkDisplay], sequence_number, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
return NSDragOperationNone;
|
NSInteger sequence_number = [sender draggingSequenceNumber];
|
||||||
|
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||||
|
GdkDrop *drop = _gdk_macos_display_find_drop (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||||
|
NSPoint location = [sender draggingLocation];
|
||||||
|
|
||||||
|
if (drop == NULL)
|
||||||
|
return NSDragOperationNone;
|
||||||
|
|
||||||
|
_gdk_macos_drop_update_actions (GDK_MACOS_DROP (drop), sender);
|
||||||
|
|
||||||
|
gdk_drop_emit_motion_event (drop,
|
||||||
|
TRUE,
|
||||||
|
location.x,
|
||||||
|
GDK_SURFACE (gdk_surface)->height - location.y,
|
||||||
|
GDK_CURRENT_TIME);
|
||||||
|
|
||||||
|
return _gdk_macos_drop_operation (GDK_MACOS_DROP (drop));
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||||
{
|
{
|
||||||
return YES;
|
NSInteger sequence_number = [sender draggingSequenceNumber];
|
||||||
|
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||||
|
GdkDrop *drop = _gdk_macos_display_find_drop (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||||
|
NSPoint location = [sender draggingLocation];
|
||||||
|
|
||||||
|
if (drop == NULL)
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
gdk_drop_emit_drop_event (drop,
|
||||||
|
TRUE,
|
||||||
|
location.x,
|
||||||
|
GDK_SURFACE (gdk_surface)->height - location.y,
|
||||||
|
GDK_CURRENT_TIME);
|
||||||
|
|
||||||
|
gdk_drop_emit_leave_event (drop, TRUE, GDK_CURRENT_TIME);
|
||||||
|
|
||||||
|
return GDK_MACOS_DROP (drop)->finish_action != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)wantsPeriodicDraggingUpdates
|
-(BOOL)wantsPeriodicDraggingUpdates
|
||||||
|
|||||||
@@ -35,11 +35,24 @@ typedef NSString *NSPasteboardType;
|
|||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
||||||
|
|
||||||
GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
|
GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
|
||||||
void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
|
void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
|
||||||
NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||||
NSPasteboardType *alternate);
|
NSPasteboardType *alternate);
|
||||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||||
|
void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
|
||||||
|
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
|
||||||
|
void _gdk_macos_pasteboard_read_async (GObject *object,
|
||||||
|
NSPasteboard *pasteboard,
|
||||||
|
GdkContentFormats *formats,
|
||||||
|
int io_priority,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
const char **out_mime_type,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||||
{
|
{
|
||||||
|
|||||||
+177
-133
@@ -172,17 +172,15 @@ populate_content_formats (GdkContentFormatsBuilder *builder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GdkContentFormats *
|
static GdkContentFormats *
|
||||||
load_offer_formats (GdkMacosClipboard *self)
|
load_offer_formats (NSPasteboard *pasteboard)
|
||||||
{
|
{
|
||||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||||
|
|
||||||
GdkContentFormatsBuilder *builder;
|
GdkContentFormatsBuilder *builder;
|
||||||
GdkContentFormats *formats;
|
GdkContentFormats *formats;
|
||||||
|
|
||||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
|
||||||
|
|
||||||
builder = gdk_content_formats_builder_new ();
|
builder = gdk_content_formats_builder_new ();
|
||||||
for (NSPasteboardType type in [self->pasteboard types])
|
for (NSPasteboardType type in [pasteboard types])
|
||||||
populate_content_formats (builder, type);
|
populate_content_formats (builder, type);
|
||||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||||
|
|
||||||
@@ -201,7 +199,7 @@ _gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
|||||||
|
|
||||||
change_count = [self->pasteboard changeCount];
|
change_count = [self->pasteboard changeCount];
|
||||||
|
|
||||||
formats = load_offer_formats (self);
|
formats = load_offer_formats (self->pasteboard);
|
||||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
|
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
|
||||||
gdk_content_formats_unref (formats);
|
gdk_content_formats_unref (formats);
|
||||||
|
|
||||||
@@ -225,125 +223,13 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
|||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
_gdk_macos_pasteboard_read_async (G_OBJECT (clipboard),
|
||||||
|
GDK_MACOS_CLIPBOARD (clipboard)->pasteboard,
|
||||||
GdkMacosClipboard *self = (GdkMacosClipboard *)clipboard;
|
formats,
|
||||||
GdkContentFormats *offer_formats = NULL;
|
io_priority,
|
||||||
const char *mime_type;
|
cancellable,
|
||||||
GInputStream *stream = NULL;
|
callback,
|
||||||
GTask *task = NULL;
|
user_data);
|
||||||
|
|
||||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
|
||||||
g_assert (formats != NULL);
|
|
||||||
|
|
||||||
task = g_task_new (self, cancellable, callback, user_data);
|
|
||||||
g_task_set_source_tag (task, _gdk_macos_clipboard_read_async);
|
|
||||||
g_task_set_priority (task, io_priority);
|
|
||||||
|
|
||||||
offer_formats = load_offer_formats (GDK_MACOS_CLIPBOARD (clipboard));
|
|
||||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
|
||||||
|
|
||||||
if (mime_type == NULL)
|
|
||||||
{
|
|
||||||
g_task_return_new_error (task,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_NOT_SUPPORTED,
|
|
||||||
"%s",
|
|
||||||
_("No compatible transfer format found"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
|
||||||
{
|
|
||||||
NSString *nsstr = [self->pasteboard stringForType:NSPasteboardTypeString];
|
|
||||||
|
|
||||||
if (nsstr != NULL)
|
|
||||||
{
|
|
||||||
const char *str = [nsstr UTF8String];
|
|
||||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
|
||||||
strlen (str) + 1,
|
|
||||||
g_free);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
|
||||||
{
|
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
|
||||||
|
|
||||||
if ([[self->pasteboard types] containsObject:PTYPE(FILE_URL)])
|
|
||||||
{
|
|
||||||
GString *str = g_string_new (NULL);
|
|
||||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
|
||||||
gsize n_files = [files count];
|
|
||||||
char *data;
|
|
||||||
guint len;
|
|
||||||
|
|
||||||
for (gsize i = 0; i < n_files; ++i)
|
|
||||||
{
|
|
||||||
NSString* uriString = [files objectAtIndex:i];
|
|
||||||
uriString = [@"file://" stringByAppendingString:uriString];
|
|
||||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
|
|
||||||
g_string_append_printf (str,
|
|
||||||
"%s\r\n",
|
|
||||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = str->len;
|
|
||||||
data = g_string_free (str, FALSE);
|
|
||||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
|
||||||
}
|
|
||||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
|
||||||
{
|
|
||||||
NSColorSpace *colorspace;
|
|
||||||
NSColor *nscolor;
|
|
||||||
guint16 color[4];
|
|
||||||
|
|
||||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
|
||||||
nscolor = [[NSColor colorFromPasteboard:self->pasteboard]
|
|
||||||
colorUsingColorSpace:colorspace];
|
|
||||||
|
|
||||||
color[0] = 0xffff * [nscolor redComponent];
|
|
||||||
color[1] = 0xffff * [nscolor greenComponent];
|
|
||||||
color[2] = 0xffff * [nscolor blueComponent];
|
|
||||||
color[3] = 0xffff * [nscolor alphaComponent];
|
|
||||||
|
|
||||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
|
||||||
sizeof color,
|
|
||||||
g_free);
|
|
||||||
}
|
|
||||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
|
||||||
{
|
|
||||||
NSData *data = [self->pasteboard dataForType:PTYPE(TIFF)];
|
|
||||||
stream = create_stream_from_nsdata (data);
|
|
||||||
}
|
|
||||||
else if (strcmp (mime_type, "image/png") == 0)
|
|
||||||
{
|
|
||||||
NSData *data = [self->pasteboard dataForType:PTYPE(PNG)];
|
|
||||||
stream = create_stream_from_nsdata (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream != NULL)
|
|
||||||
{
|
|
||||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
|
||||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_task_return_new_error (task,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_FAILED,
|
|
||||||
_("Failed to decode contents with mime-type of '%s'"),
|
|
||||||
mime_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
g_clear_object (&task);
|
|
||||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
|
||||||
|
|
||||||
GDK_END_MACOS_ALLOC_POOL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GInputStream *
|
static GInputStream *
|
||||||
@@ -352,15 +238,7 @@ _gdk_macos_clipboard_read_finish (GdkClipboard *clipboard,
|
|||||||
const char **out_mime_type,
|
const char **out_mime_type,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GTask *task = (GTask *)result;
|
return _gdk_macos_pasteboard_read_finish (G_OBJECT (clipboard), result, out_mime_type, error);
|
||||||
|
|
||||||
g_assert (GDK_IS_MACOS_CLIPBOARD (clipboard));
|
|
||||||
g_assert (G_IS_TASK (task));
|
|
||||||
|
|
||||||
if (out_mime_type != NULL)
|
|
||||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
|
||||||
|
|
||||||
return g_task_propagate_pointer (task, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -622,4 +500,170 @@ on_data_ready_cb (GObject *object,
|
|||||||
write_request_free (wr);
|
write_request_free (wr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_macos_clipboard_register_drag_types (NSWindow *window)
|
||||||
|
{
|
||||||
|
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
|
||||||
|
PTYPE(PBOARD),
|
||||||
|
PTYPE(URL),
|
||||||
|
PTYPE(FILE_URL),
|
||||||
|
PTYPE(COLOR),
|
||||||
|
PTYPE(TIFF),
|
||||||
|
PTYPE(PNG),
|
||||||
|
nil]];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
GdkContentFormats *
|
||||||
|
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
|
||||||
|
{
|
||||||
|
return load_offer_formats (pasteboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_macos_pasteboard_read_async (GObject *object,
|
||||||
|
NSPasteboard *pasteboard,
|
||||||
|
GdkContentFormats *formats,
|
||||||
|
int io_priority,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||||
|
|
||||||
|
GdkContentFormats *offer_formats = NULL;
|
||||||
|
const char *mime_type;
|
||||||
|
GInputStream *stream = NULL;
|
||||||
|
GTask *task = NULL;
|
||||||
|
|
||||||
|
g_assert (G_IS_OBJECT (object));
|
||||||
|
g_assert (pasteboard != NULL);
|
||||||
|
g_assert (formats != NULL);
|
||||||
|
|
||||||
|
task = g_task_new (object, cancellable, callback, user_data);
|
||||||
|
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
|
||||||
|
g_task_set_priority (task, io_priority);
|
||||||
|
|
||||||
|
offer_formats = load_offer_formats (pasteboard);
|
||||||
|
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||||
|
|
||||||
|
if (mime_type == NULL)
|
||||||
|
{
|
||||||
|
g_task_return_new_error (task,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
"%s",
|
||||||
|
_("No compatible transfer format found"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||||
|
{
|
||||||
|
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
|
||||||
|
|
||||||
|
if (nsstr != NULL)
|
||||||
|
{
|
||||||
|
const char *str = [nsstr UTF8String];
|
||||||
|
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||||
|
strlen (str) + 1,
|
||||||
|
g_free);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||||
|
{
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||||
|
|
||||||
|
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||||
|
{
|
||||||
|
GString *str = g_string_new (NULL);
|
||||||
|
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||||
|
gsize n_files = [files count];
|
||||||
|
char *data;
|
||||||
|
guint len;
|
||||||
|
|
||||||
|
for (gsize i = 0; i < n_files; ++i)
|
||||||
|
{
|
||||||
|
NSString* uriString = [files objectAtIndex:i];
|
||||||
|
uriString = [@"file://" stringByAppendingString:uriString];
|
||||||
|
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
g_string_append_printf (str,
|
||||||
|
"%s\r\n",
|
||||||
|
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = str->len;
|
||||||
|
data = g_string_free (str, FALSE);
|
||||||
|
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||||
|
}
|
||||||
|
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||||
|
{
|
||||||
|
NSColorSpace *colorspace;
|
||||||
|
NSColor *nscolor;
|
||||||
|
guint16 color[4];
|
||||||
|
|
||||||
|
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||||
|
nscolor = [[NSColor colorFromPasteboard:pasteboard]
|
||||||
|
colorUsingColorSpace:colorspace];
|
||||||
|
|
||||||
|
color[0] = 0xffff * [nscolor redComponent];
|
||||||
|
color[1] = 0xffff * [nscolor greenComponent];
|
||||||
|
color[2] = 0xffff * [nscolor blueComponent];
|
||||||
|
color[3] = 0xffff * [nscolor alphaComponent];
|
||||||
|
|
||||||
|
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||||
|
sizeof color,
|
||||||
|
g_free);
|
||||||
|
}
|
||||||
|
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||||
|
{
|
||||||
|
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
|
||||||
|
stream = create_stream_from_nsdata (data);
|
||||||
|
}
|
||||||
|
else if (strcmp (mime_type, "image/png") == 0)
|
||||||
|
{
|
||||||
|
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
|
||||||
|
stream = create_stream_from_nsdata (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream != NULL)
|
||||||
|
{
|
||||||
|
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||||
|
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_task_return_new_error (task,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_FAILED,
|
||||||
|
_("Failed to decode contents with mime-type of '%s'"),
|
||||||
|
mime_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
g_clear_object (&task);
|
||||||
|
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||||
|
|
||||||
|
GDK_END_MACOS_ALLOC_POOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GInputStream *
|
||||||
|
_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
const char **out_mime_type,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GTask *task = (GTask *)result;
|
||||||
|
|
||||||
|
g_assert (G_IS_OBJECT (object));
|
||||||
|
g_assert (G_IS_TASK (task));
|
||||||
|
|
||||||
|
if (out_mime_type != NULL)
|
||||||
|
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||||
|
|
||||||
|
return g_task_propagate_pointer (task, error);
|
||||||
|
}
|
||||||
|
|||||||
@@ -81,6 +81,10 @@ struct _GdkMacosDisplay
|
|||||||
/* The surface that is receiving keyboard events */
|
/* The surface that is receiving keyboard events */
|
||||||
GdkMacosSurface *keyboard_surface;
|
GdkMacosSurface *keyboard_surface;
|
||||||
|
|
||||||
|
/* [NSDraggingInfo draggingSequenceNumber] to GdkMacosDr(ag,op) */
|
||||||
|
GHashTable *active_drags;
|
||||||
|
GHashTable *active_drops;
|
||||||
|
|
||||||
/* Used to translate from quartz coordinate space to GDK */
|
/* Used to translate from quartz coordinate space to GDK */
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
@@ -160,6 +164,16 @@ void _gdk_macos_display_warp_pointer (GdkMacosDisp
|
|||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
NSEvent *_gdk_macos_display_get_nsevent (GdkEvent *event);
|
NSEvent *_gdk_macos_display_get_nsevent (GdkEvent *event);
|
||||||
|
GdkDrag *_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number);
|
||||||
|
GdkDrop *_gdk_macos_display_find_drop (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number);
|
||||||
|
void _gdk_macos_display_set_drag (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number,
|
||||||
|
GdkDrag *drag);
|
||||||
|
void _gdk_macos_display_set_drop (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number,
|
||||||
|
GdkDrop *drop);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -788,6 +788,9 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
|||||||
NSRect view_frame;
|
NSRect view_frame;
|
||||||
|
|
||||||
view = (GdkMacosBaseView *)[nswindow contentView];
|
view = (GdkMacosBaseView *)[nswindow contentView];
|
||||||
|
if (!GDK_IS_MACOS_BASE_VIEW (view))
|
||||||
|
goto find_under_pointer;
|
||||||
|
|
||||||
surface = GDK_SURFACE ([view gdkSurface]);
|
surface = GDK_SURFACE ([view gdkSurface]);
|
||||||
|
|
||||||
point = [nsevent locationInWindow];
|
point = [nsevent locationInWindow];
|
||||||
@@ -846,6 +849,8 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_under_pointer:
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
/* Fallback used when no NSSurface set. This happens e.g. when
|
/* Fallback used when no NSSurface set. This happens e.g. when
|
||||||
@@ -864,17 +869,24 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
|||||||
static GdkMacosSurface *
|
static GdkMacosSurface *
|
||||||
find_surface_for_keyboard_event (NSEvent *nsevent)
|
find_surface_for_keyboard_event (NSEvent *nsevent)
|
||||||
{
|
{
|
||||||
GdkMacosBaseView *view = (GdkMacosBaseView *)[[nsevent window] contentView];
|
NSView *nsview = [[nsevent window] contentView];
|
||||||
GdkSurface *surface = GDK_SURFACE ([view gdkSurface]);
|
|
||||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
|
||||||
GdkSeat *seat = gdk_display_get_default_seat (display);
|
|
||||||
GdkDevice *device = gdk_seat_get_keyboard (seat);
|
|
||||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (display, device);
|
|
||||||
|
|
||||||
if (grab && grab->surface && !grab->owner_events)
|
if (GDK_IS_MACOS_BASE_VIEW (nsview))
|
||||||
return GDK_MACOS_SURFACE (grab->surface);
|
{
|
||||||
|
GdkMacosBaseView *view = (GdkMacosBaseView *)nsview;
|
||||||
|
GdkSurface *surface = GDK_SURFACE ([view gdkSurface]);
|
||||||
|
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||||
|
GdkSeat *seat = gdk_display_get_default_seat (display);
|
||||||
|
GdkDevice *device = gdk_seat_get_keyboard (seat);
|
||||||
|
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (display, device);
|
||||||
|
|
||||||
return GDK_MACOS_SURFACE (surface);
|
if (grab && grab->surface && !grab->owner_events)
|
||||||
|
return GDK_MACOS_SURFACE (grab->surface);
|
||||||
|
|
||||||
|
return GDK_MACOS_SURFACE (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkMacosSurface *
|
static GdkMacosSurface *
|
||||||
@@ -1090,7 +1102,8 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
|||||||
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)))
|
if (!(window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)) ||
|
||||||
|
!GDK_IS_MACOS_WINDOW (window))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Ignore events and break grabs while the window is being
|
/* Ignore events and break grabs while the window is being
|
||||||
|
|||||||
+65
-11
@@ -31,6 +31,8 @@
|
|||||||
#include "gdkmacoscairocontext-private.h"
|
#include "gdkmacoscairocontext-private.h"
|
||||||
#include "gdkmacoseventsource-private.h"
|
#include "gdkmacoseventsource-private.h"
|
||||||
#include "gdkmacosdisplay-private.h"
|
#include "gdkmacosdisplay-private.h"
|
||||||
|
#include "gdkmacosdrag-private.h"
|
||||||
|
#include "gdkmacosdrop-private.h"
|
||||||
#include "gdkmacosglcontext-private.h"
|
#include "gdkmacosglcontext-private.h"
|
||||||
#include "gdkmacoskeymap-private.h"
|
#include "gdkmacoskeymap-private.h"
|
||||||
#include "gdkmacosmonitor-private.h"
|
#include "gdkmacosmonitor-private.h"
|
||||||
@@ -635,17 +637,13 @@ gdk_macos_display_load_clipboard (GdkMacosDisplay *self)
|
|||||||
GDK_DISPLAY (self)->clipboard = _gdk_macos_clipboard_new (self);
|
GDK_DISPLAY (self)->clipboard = _gdk_macos_clipboard_new (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static GdkGLContext *
|
||||||
gdk_macos_display_make_gl_context_current (GdkDisplay *display,
|
gdk_macos_display_init_gl (GdkDisplay *display,
|
||||||
GdkGLContext *gl_context)
|
GError **error)
|
||||||
{
|
{
|
||||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
return g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||||
g_assert (!gl_context || GDK_IS_MACOS_GL_CONTEXT (gl_context));
|
"display", display,
|
||||||
|
NULL);
|
||||||
if (gl_context == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return _gdk_macos_gl_context_make_current (GDK_MACOS_GL_CONTEXT (gl_context));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -663,6 +661,8 @@ gdk_macos_display_finalize (GObject *object)
|
|||||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
g_clear_pointer (&self->active_drags, g_hash_table_unref);
|
||||||
|
g_clear_pointer (&self->active_drops, g_hash_table_unref);
|
||||||
g_clear_object (&GDK_DISPLAY (self)->clipboard);
|
g_clear_object (&GDK_DISPLAY (self)->clipboard);
|
||||||
g_clear_pointer (&self->frame_source, g_source_unref);
|
g_clear_pointer (&self->frame_source, g_source_unref);
|
||||||
g_clear_object (&self->monitors);
|
g_clear_object (&self->monitors);
|
||||||
@@ -691,7 +691,7 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
|
|||||||
display_class->get_name = gdk_macos_display_get_name;
|
display_class->get_name = gdk_macos_display_get_name;
|
||||||
display_class->get_setting = gdk_macos_display_get_setting;
|
display_class->get_setting = gdk_macos_display_get_setting;
|
||||||
display_class->has_pending = gdk_macos_display_has_pending;
|
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->notify_startup_complete = gdk_macos_display_notify_startup_complete;
|
||||||
display_class->queue_events = gdk_macos_display_queue_events;
|
display_class->queue_events = gdk_macos_display_queue_events;
|
||||||
display_class->sync = gdk_macos_display_sync;
|
display_class->sync = gdk_macos_display_sync;
|
||||||
@@ -701,6 +701,8 @@ static void
|
|||||||
gdk_macos_display_init (GdkMacosDisplay *self)
|
gdk_macos_display_init (GdkMacosDisplay *self)
|
||||||
{
|
{
|
||||||
self->monitors = g_list_store_new (GDK_TYPE_MONITOR);
|
self->monitors = g_list_store_new (GDK_TYPE_MONITOR);
|
||||||
|
self->active_drags = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
|
||||||
|
self->active_drops = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
|
||||||
|
|
||||||
gdk_display_set_composited (GDK_DISPLAY (self), TRUE);
|
gdk_display_set_composited (GDK_DISPLAY (self), TRUE);
|
||||||
gdk_display_set_input_shapes (GDK_DISPLAY (self), FALSE);
|
gdk_display_set_input_shapes (GDK_DISPLAY (self), FALSE);
|
||||||
@@ -1113,3 +1115,55 @@ _gdk_macos_display_get_nsevent (GdkEvent *event)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GdkDrag *
|
||||||
|
_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), NULL);
|
||||||
|
|
||||||
|
return g_hash_table_lookup (self->active_drags, GSIZE_TO_POINTER (sequence_number));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_macos_display_set_drag (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number,
|
||||||
|
GdkDrag *drag)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||||
|
g_return_if_fail (!drag || GDK_IS_MACOS_DRAG (drag));
|
||||||
|
|
||||||
|
if (drag)
|
||||||
|
g_hash_table_insert (self->active_drags,
|
||||||
|
GSIZE_TO_POINTER (sequence_number),
|
||||||
|
g_object_ref (drag));
|
||||||
|
else
|
||||||
|
g_hash_table_remove (self->active_drags,
|
||||||
|
GSIZE_TO_POINTER (sequence_number));
|
||||||
|
}
|
||||||
|
|
||||||
|
GdkDrop *
|
||||||
|
_gdk_macos_display_find_drop (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), NULL);
|
||||||
|
|
||||||
|
return g_hash_table_lookup (self->active_drops, GSIZE_TO_POINTER (sequence_number));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_macos_display_set_drop (GdkMacosDisplay *self,
|
||||||
|
NSInteger sequence_number,
|
||||||
|
GdkDrop *drop)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||||
|
g_return_if_fail (!drop || GDK_IS_MACOS_DROP (drop));
|
||||||
|
|
||||||
|
if (drop)
|
||||||
|
g_hash_table_insert (self->active_drops,
|
||||||
|
GSIZE_TO_POINTER (sequence_number),
|
||||||
|
g_object_ref (drop));
|
||||||
|
else
|
||||||
|
g_hash_table_remove (self->active_drops,
|
||||||
|
GSIZE_TO_POINTER (sequence_number));
|
||||||
|
}
|
||||||
|
|||||||
@@ -326,12 +326,10 @@ gdk_drag_update (GdkDrag *drag,
|
|||||||
&suggested_action,
|
&suggested_action,
|
||||||
&possible_actions);
|
&possible_actions);
|
||||||
|
|
||||||
_gdk_macos_drag_surface_drag_motion (self->drag_surface,
|
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
|
||||||
x_root - self->hot_x,
|
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||||
y_root - self->hot_y,
|
x_root - self->hot_x,
|
||||||
suggested_action,
|
y_root - self->hot_y);
|
||||||
possible_actions,
|
|
||||||
evtime);
|
|
||||||
|
|
||||||
if (!self->did_update)
|
if (!self->did_update)
|
||||||
{
|
{
|
||||||
@@ -339,6 +337,8 @@ gdk_drag_update (GdkDrag *drag,
|
|||||||
self->start_y = self->last_y;
|
self->start_y = self->last_y;
|
||||||
self->did_update = TRUE;
|
self->did_update = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gdk_drag_set_actions (drag, possible_actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|||||||
@@ -31,19 +31,13 @@ typedef struct _GdkMacosDragSurfaceClass GdkMacosDragSurfaceClass;
|
|||||||
#define GDK_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DRAG_SURFACE, GdkMacosDragSurface))
|
#define GDK_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DRAG_SURFACE, GdkMacosDragSurface))
|
||||||
#define GDK_IS_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG_SURFACE))
|
#define GDK_IS_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG_SURFACE))
|
||||||
|
|
||||||
GType _gdk_macos_drag_surface_get_type (void);
|
GType _gdk_macos_drag_surface_get_type (void);
|
||||||
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
||||||
GdkFrameClock *frame_clock,
|
GdkFrameClock *frame_clock,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
void _gdk_macos_drag_surface_drag_motion (GdkMacosDragSurface *self,
|
|
||||||
int x_root,
|
|
||||||
int y_root,
|
|
||||||
GdkDragAction suggested_action,
|
|
||||||
GdkDragAction possible_actions,
|
|
||||||
guint32 evtime);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -123,16 +123,3 @@ _gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
|||||||
|
|
||||||
return g_steal_pointer (&self);
|
return g_steal_pointer (&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
_gdk_macos_drag_surface_drag_motion (GdkMacosDragSurface *self,
|
|
||||||
int x_root,
|
|
||||||
int y_root,
|
|
||||||
GdkDragAction suggested_action,
|
|
||||||
GdkDragAction possible_actions,
|
|
||||||
guint32 evtime)
|
|
||||||
{
|
|
||||||
g_return_if_fail (GDK_IS_MACOS_DRAG_SURFACE (self));
|
|
||||||
|
|
||||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self), x_root, y_root);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GDK_MACOS_DROP_PRIVATE_H__
|
||||||
|
#define __GDK_MACOS_DROP_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <AppKit/AppKit.h>
|
||||||
|
|
||||||
|
#include "gdkdropprivate.h"
|
||||||
|
|
||||||
|
#include "gdkmacossurface-private.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GDK_TYPE_MACOS_DROP (gdk_macos_drop_get_type ())
|
||||||
|
#define GDK_MACOS_DROP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DROP, GdkMacosDrop))
|
||||||
|
#define GDK_MACOS_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_MACOS_DROP, GdkMacosDropClass))
|
||||||
|
#define GDK_IS_MACOS_DROP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DROP))
|
||||||
|
#define GDK_IS_MACOS_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_MACOS_DROP))
|
||||||
|
#define GDK_MACOS_DROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_MACOS_DROP, GdkMacosDropClass))
|
||||||
|
|
||||||
|
typedef struct _GdkMacosDrop GdkMacosDrop;
|
||||||
|
typedef struct _GdkMacosDropClass GdkMacosDropClass;
|
||||||
|
|
||||||
|
struct _GdkMacosDrop
|
||||||
|
{
|
||||||
|
GdkDrop parent_instance;
|
||||||
|
|
||||||
|
NSPasteboard *pasteboard;
|
||||||
|
|
||||||
|
GdkDragAction all_actions;
|
||||||
|
GdkDragAction preferred_action;
|
||||||
|
GdkDragAction finish_action;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GdkMacosDropClass
|
||||||
|
{
|
||||||
|
GdkDropClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gdk_macos_drop_get_type (void) G_GNUC_CONST;
|
||||||
|
GdkMacosDrop *_gdk_macos_drop_new (GdkMacosSurface *surface,
|
||||||
|
id<NSDraggingInfo> info);
|
||||||
|
NSDragOperation _gdk_macos_drop_operation (GdkMacosDrop *self);
|
||||||
|
void _gdk_macos_drop_update_actions (GdkMacosDrop *self,
|
||||||
|
id<NSDraggingInfo> info);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GDK_MACOS_DROP_PRIVATE_H__ */
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2021 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gdkmacosclipboard-private.h"
|
||||||
|
#include "gdkmacosdisplay-private.h"
|
||||||
|
#include "gdkmacosdrag-private.h"
|
||||||
|
#include "gdkmacosdrop-private.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GdkMacosDrop, gdk_macos_drop, GDK_TYPE_DROP)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_macos_drop_status (GdkDrop *drop,
|
||||||
|
GdkDragAction actions,
|
||||||
|
GdkDragAction preferred)
|
||||||
|
{
|
||||||
|
GdkMacosDrop *self = (GdkMacosDrop *)drop;
|
||||||
|
|
||||||
|
g_assert (GDK_IS_MACOS_DROP (self));
|
||||||
|
|
||||||
|
self->all_actions = actions;
|
||||||
|
self->preferred_action = preferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_macos_drop_read_async (GdkDrop *drop,
|
||||||
|
GdkContentFormats *content_formats,
|
||||||
|
int io_priority,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
_gdk_macos_pasteboard_read_async (G_OBJECT (drop),
|
||||||
|
GDK_MACOS_DROP (drop)->pasteboard,
|
||||||
|
content_formats,
|
||||||
|
io_priority,
|
||||||
|
cancellable,
|
||||||
|
callback,
|
||||||
|
user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GInputStream *
|
||||||
|
gdk_macos_drop_read_finish (GdkDrop *drop,
|
||||||
|
GAsyncResult *result,
|
||||||
|
const char **out_mime_type,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return _gdk_macos_pasteboard_read_finish (G_OBJECT (drop), result, out_mime_type, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_macos_drop_finish (GdkDrop *drop,
|
||||||
|
GdkDragAction action)
|
||||||
|
{
|
||||||
|
g_assert (GDK_IS_MACOS_DROP (drop));
|
||||||
|
|
||||||
|
GDK_MACOS_DROP (drop)->finish_action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_macos_drop_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GdkMacosDrop *self = (GdkMacosDrop *)object;
|
||||||
|
|
||||||
|
if (self->pasteboard)
|
||||||
|
{
|
||||||
|
[self->pasteboard release];
|
||||||
|
self->pasteboard = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gdk_macos_drop_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_macos_drop_class_init (GdkMacosDropClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GdkDropClass *drop_class = GDK_DROP_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gdk_macos_drop_finalize;
|
||||||
|
|
||||||
|
drop_class->status = gdk_macos_drop_status;
|
||||||
|
drop_class->read_async = gdk_macos_drop_read_async;
|
||||||
|
drop_class->read_finish = gdk_macos_drop_read_finish;
|
||||||
|
drop_class->finish = gdk_macos_drop_finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_macos_drop_init (GdkMacosDrop *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_macos_drop_update_actions (GdkMacosDrop *self,
|
||||||
|
id<NSDraggingInfo> info)
|
||||||
|
{
|
||||||
|
NSDragOperation op;
|
||||||
|
GdkDragAction actions = 0;
|
||||||
|
|
||||||
|
g_assert (GDK_IS_MACOS_DROP (self));
|
||||||
|
|
||||||
|
op = [info draggingSourceOperationMask];
|
||||||
|
|
||||||
|
if (op & NSDragOperationCopy)
|
||||||
|
actions |= GDK_ACTION_COPY;
|
||||||
|
|
||||||
|
if (op & NSDragOperationLink)
|
||||||
|
actions |= GDK_ACTION_LINK;
|
||||||
|
|
||||||
|
if (op & NSDragOperationMove)
|
||||||
|
actions |= GDK_ACTION_MOVE;
|
||||||
|
|
||||||
|
gdk_drop_set_actions (GDK_DROP (self), actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
GdkMacosDrop *
|
||||||
|
_gdk_macos_drop_new (GdkMacosSurface *surface,
|
||||||
|
id<NSDraggingInfo> info)
|
||||||
|
{
|
||||||
|
GdkDrag *drag = NULL;
|
||||||
|
GdkContentFormats *content_formats;
|
||||||
|
GdkMacosDrop *self;
|
||||||
|
GdkDisplay *display;
|
||||||
|
GdkDevice *device;
|
||||||
|
GdkSeat *seat;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (surface), NULL);
|
||||||
|
g_return_val_if_fail (info != NULL, NULL);
|
||||||
|
|
||||||
|
display = gdk_surface_get_display (GDK_SURFACE (surface));
|
||||||
|
seat = gdk_display_get_default_seat (display);
|
||||||
|
device = gdk_seat_get_pointer (seat);
|
||||||
|
drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), [info draggingSequenceNumber]);
|
||||||
|
|
||||||
|
content_formats = _gdk_macos_pasteboard_load_formats ([info draggingPasteboard]);
|
||||||
|
|
||||||
|
self = g_object_new (GDK_TYPE_MACOS_DROP,
|
||||||
|
"device", device,
|
||||||
|
"drag", drag,
|
||||||
|
"formats", content_formats,
|
||||||
|
"surface", surface,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
self->pasteboard = [[info draggingPasteboard] retain];
|
||||||
|
|
||||||
|
_gdk_macos_drop_update_actions (self, info);
|
||||||
|
|
||||||
|
gdk_content_formats_unref (content_formats);
|
||||||
|
|
||||||
|
return g_steal_pointer (&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDragOperation
|
||||||
|
_gdk_macos_drop_operation (GdkMacosDrop *self)
|
||||||
|
{
|
||||||
|
if (self->preferred_action & GDK_ACTION_LINK)
|
||||||
|
return NSDragOperationLink;
|
||||||
|
|
||||||
|
if (self->preferred_action & GDK_ACTION_MOVE)
|
||||||
|
return NSDragOperationMove;
|
||||||
|
|
||||||
|
if (self->preferred_action & GDK_ACTION_COPY)
|
||||||
|
return NSDragOperationCopy;
|
||||||
|
|
||||||
|
return NSDragOperationNone;
|
||||||
|
}
|
||||||
@@ -19,12 +19,14 @@
|
|||||||
#ifndef __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
#ifndef __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||||
#define __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
#define __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "gdkmacosglcontext.h"
|
||||||
|
|
||||||
#include "gdkglcontextprivate.h"
|
#include "gdkglcontextprivate.h"
|
||||||
#include "gdkdisplayprivate.h"
|
#include "gdkdisplayprivate.h"
|
||||||
#include "gdksurface.h"
|
#include "gdksurface.h"
|
||||||
#include "gdkinternals.h"
|
#include "gdkinternals.h"
|
||||||
|
|
||||||
#include "gdkmacosglcontext.h"
|
#include "gdkmacosdisplay.h"
|
||||||
#include "gdkmacossurface.h"
|
#include "gdkmacossurface.h"
|
||||||
|
|
||||||
#import <OpenGL/OpenGL.h>
|
#import <OpenGL/OpenGL.h>
|
||||||
@@ -55,11 +57,6 @@ struct _GdkMacosGLContextClass
|
|||||||
GdkGLContextClass parent_class;
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ ensure_gl_view (GdkMacosGLContext *self)
|
|||||||
[nsview setPostsFrameChangedNotifications: YES];
|
[nsview setPostsFrameChangedNotifications: YES];
|
||||||
[nsview setNeedsDisplay:YES];
|
[nsview setNeedsDisplay:YES];
|
||||||
[nswindow setContentView:nsview];
|
[nswindow setContentView:nsview];
|
||||||
|
[nswindow makeFirstResponder:nsview];
|
||||||
[nsview release];
|
[nsview release];
|
||||||
|
|
||||||
if (self->dummy_view != NULL)
|
if (self->dummy_view != NULL)
|
||||||
@@ -169,12 +170,12 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
|||||||
{
|
{
|
||||||
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
|
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
|
||||||
GdkSurface *surface;
|
GdkSurface *surface;
|
||||||
|
GdkDisplay *display;
|
||||||
NSOpenGLContext *shared_gl_context = nil;
|
NSOpenGLContext *shared_gl_context = nil;
|
||||||
NSOpenGLContext *gl_context;
|
NSOpenGLContext *gl_context;
|
||||||
NSOpenGLPixelFormat *pixelFormat;
|
NSOpenGLPixelFormat *pixelFormat;
|
||||||
CGLContextObj cgl_context;
|
CGLContextObj cgl_context;
|
||||||
GdkGLContext *shared;
|
GdkGLContext *shared;
|
||||||
GdkGLContext *shared_data;
|
|
||||||
NSOpenGLContext *existing;
|
NSOpenGLContext *existing;
|
||||||
GLint sync_to_framerate = 1;
|
GLint sync_to_framerate = 1;
|
||||||
GLint validate = 0;
|
GLint validate = 0;
|
||||||
@@ -191,21 +192,16 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
|||||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||||
|
|
||||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||||
shared = gdk_gl_context_get_shared_context (context);
|
display = gdk_gl_context_get_display (context);
|
||||||
shared_data = gdk_surface_get_shared_data_gl_context (surface);
|
shared = gdk_display_get_gl_context (display);
|
||||||
|
|
||||||
if (shared != NULL)
|
if (shared != NULL)
|
||||||
{
|
{
|
||||||
if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
|
if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
|
||||||
return FALSE;
|
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,
|
OPENGL,
|
||||||
g_message ("Creating NSOpenGLContext (version %d.%d)",
|
g_message ("Creating NSOpenGLContext (version %d.%d)",
|
||||||
major, minor));
|
major, minor));
|
||||||
@@ -252,7 +248,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
|||||||
|
|
||||||
GLint renderer_id = 0;
|
GLint renderer_id = 0;
|
||||||
[gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
|
[gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
|
||||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
|
GDK_DISPLAY_NOTE (display,
|
||||||
OPENGL,
|
OPENGL,
|
||||||
g_message ("Created NSOpenGLContext[%p] using %s",
|
g_message ("Created NSOpenGLContext[%p] using %s",
|
||||||
gl_context,
|
gl_context,
|
||||||
@@ -314,9 +310,7 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
|||||||
* want to replace our damage region for the next frame (to avoid
|
* want to replace our damage region for the next frame (to avoid
|
||||||
* doing it multiple times).
|
* doing it multiple times).
|
||||||
*/
|
*/
|
||||||
if (!self->is_attached &&
|
ensure_gl_view (self);
|
||||||
gdk_gl_context_get_shared_context (GDK_GL_CONTEXT (context)))
|
|
||||||
ensure_gl_view (self);
|
|
||||||
|
|
||||||
if (self->needs_resize)
|
if (self->needs_resize)
|
||||||
{
|
{
|
||||||
@@ -409,6 +403,57 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
|
|||||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
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 *
|
static cairo_region_t *
|
||||||
gdk_macos_gl_context_get_damage (GdkGLContext *context)
|
gdk_macos_gl_context_get_damage (GdkGLContext *context)
|
||||||
{
|
{
|
||||||
@@ -477,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
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ _gdk_macos_seat_new (GdkMacosDisplay *display)
|
|||||||
|
|
||||||
init_devices (self);
|
init_devices (self);
|
||||||
|
|
||||||
return g_steal_pointer (&self);
|
return GDK_SEAT (g_steal_pointer (&self));
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkDeviceToolType
|
static GdkDeviceToolType
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
|||||||
drag_surface = _gdk_macos_surface_new (GDK_MACOS_DISPLAY (surface->display),
|
drag_surface = _gdk_macos_surface_new (GDK_MACOS_DISPLAY (surface->display),
|
||||||
GDK_SURFACE_TEMP,
|
GDK_SURFACE_TEMP,
|
||||||
surface,
|
surface,
|
||||||
-99, -99, 1, 1);
|
sx, sy, 1, 1);
|
||||||
drag = g_object_new (GDK_TYPE_MACOS_DRAG,
|
drag = g_object_new (GDK_TYPE_MACOS_DRAG,
|
||||||
"drag-surface", drag_surface,
|
"drag-surface", drag_surface,
|
||||||
"surface", surface,
|
"surface", surface,
|
||||||
@@ -358,20 +358,6 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
|||||||
return GDK_DRAG (g_steal_pointer (&drag));
|
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
|
static void
|
||||||
gdk_macos_surface_destroy (GdkSurface *surface,
|
gdk_macos_surface_destroy (GdkSurface *surface,
|
||||||
gboolean foreign_destroy)
|
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->get_property = gdk_macos_surface_get_property;
|
||||||
object_class->set_property = gdk_macos_surface_set_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->destroy = gdk_macos_surface_destroy;
|
||||||
surface_class->drag_begin = gdk_macos_surface_drag_begin;
|
surface_class->drag_begin = gdk_macos_surface_drag_begin;
|
||||||
surface_class->get_device_state = gdk_macos_surface_get_device_state;
|
surface_class->get_device_state = gdk_macos_surface_get_device_state;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ gdk_macos_sources = files([
|
|||||||
'gdkmacosdisplay-settings.c',
|
'gdkmacosdisplay-settings.c',
|
||||||
'gdkmacosdisplay-translate.c',
|
'gdkmacosdisplay-translate.c',
|
||||||
'gdkmacosdrag.c',
|
'gdkmacosdrag.c',
|
||||||
|
'gdkmacosdrop.c',
|
||||||
'gdkmacosdragsurface.c',
|
'gdkmacosdragsurface.c',
|
||||||
'gdkmacosglcontext.c',
|
'gdkmacosglcontext.c',
|
||||||
'gdkmacoseventsource.c',
|
'gdkmacoseventsource.c',
|
||||||
|
|||||||
@@ -1550,6 +1550,7 @@ pointer_handle_leave (void *data,
|
|||||||
GdkWaylandSeat *seat = data;
|
GdkWaylandSeat *seat = data;
|
||||||
GdkEvent *event;
|
GdkEvent *event;
|
||||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||||
|
GdkDeviceGrabInfo *grab;
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return;
|
return;
|
||||||
@@ -1561,8 +1562,11 @@ pointer_handle_leave (void *data,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||||
|
grab = _gdk_display_get_last_device_grab (seat->display,
|
||||||
|
seat->logical_pointer);
|
||||||
|
|
||||||
if (seat->pointer_info.button_modifiers != 0)
|
if (seat->pointer_info.button_modifiers != 0 &&
|
||||||
|
grab && grab->implicit)
|
||||||
{
|
{
|
||||||
gulong display_serial;
|
gulong display_serial;
|
||||||
|
|
||||||
@@ -3089,6 +3093,11 @@ seat_handle_capabilities (void *data,
|
|||||||
}
|
}
|
||||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && seat->wl_pointer)
|
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);
|
wl_pointer_release (seat->wl_pointer);
|
||||||
seat->wl_pointer = NULL;
|
seat->wl_pointer = NULL;
|
||||||
gdk_seat_device_removed (GDK_SEAT (seat), seat->pointer);
|
gdk_seat_device_removed (GDK_SEAT (seat), seat->pointer);
|
||||||
|
|||||||
@@ -432,12 +432,12 @@ gdk_registry_handle_global (void *data,
|
|||||||
display_wayland->subcompositor =
|
display_wayland->subcompositor =
|
||||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_subcompositor_interface, 1);
|
wl_registry_bind (display_wayland->wl_registry, id, &wl_subcompositor_interface, 1);
|
||||||
}
|
}
|
||||||
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0 &&
|
else if (strcmp (interface, "zwp_pointer_gestures_v1") == 0)
|
||||||
version == GDK_ZWP_POINTER_GESTURES_V1_VERSION)
|
|
||||||
{
|
{
|
||||||
display_wayland->pointer_gestures =
|
display_wayland->pointer_gestures =
|
||||||
wl_registry_bind (display_wayland->wl_registry,
|
wl_registry_bind (display_wayland->wl_registry,
|
||||||
id, &zwp_pointer_gestures_v1_interface, version);
|
id, &zwp_pointer_gestures_v1_interface,
|
||||||
|
MIN (version, GDK_ZWP_POINTER_GESTURES_V1_VERSION));
|
||||||
}
|
}
|
||||||
else if (strcmp (interface, "zwp_primary_selection_device_manager_v1") == 0)
|
else if (strcmp (interface, "zwp_primary_selection_device_manager_v1") == 0)
|
||||||
{
|
{
|
||||||
@@ -969,7 +969,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
|||||||
display_class->create_surface = _gdk_wayland_display_create_surface;
|
display_class->create_surface = _gdk_wayland_display_create_surface;
|
||||||
display_class->get_keymap = _gdk_wayland_display_get_keymap;
|
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_monitors = gdk_wayland_display_get_monitors;
|
||||||
display_class->get_monitor_at_surface = gdk_wayland_display_get_monitor_at_surface;
|
display_class->get_monitor_at_surface = gdk_wayland_display_get_monitor_at_surface;
|
||||||
@@ -991,6 +991,26 @@ gdk_wayland_display_get_toplevel_surfaces (GdkDisplay *display)
|
|||||||
return GDK_WAYLAND_DISPLAY (display)->toplevels;
|
return GDK_WAYLAND_DISPLAY (display)->toplevels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct wl_cursor_theme *
|
||||||
|
try_load_theme (GdkWaylandDisplay *display_wayland,
|
||||||
|
const char *dir,
|
||||||
|
gboolean dotdir,
|
||||||
|
const char *name,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
struct wl_cursor_theme *theme = NULL;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
path = g_build_filename (dir, dotdir ? ".icons" : "icons", name, "cursors", NULL);
|
||||||
|
|
||||||
|
if (g_file_test (path, G_FILE_TEST_IS_DIR))
|
||||||
|
theme = wl_cursor_theme_create (path, size, display_wayland->shm);
|
||||||
|
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
static struct wl_cursor_theme *
|
static struct wl_cursor_theme *
|
||||||
get_cursor_theme (GdkWaylandDisplay *display_wayland,
|
get_cursor_theme (GdkWaylandDisplay *display_wayland,
|
||||||
const char *name,
|
const char *name,
|
||||||
@@ -1000,16 +1020,18 @@ get_cursor_theme (GdkWaylandDisplay *display_wayland,
|
|||||||
struct wl_cursor_theme *theme = NULL;
|
struct wl_cursor_theme *theme = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
theme = try_load_theme (display_wayland, g_get_user_data_dir (), FALSE, name, size);
|
||||||
|
if (theme)
|
||||||
|
return theme;
|
||||||
|
|
||||||
|
theme = try_load_theme (display_wayland, g_get_home_dir (), TRUE, name, size);
|
||||||
|
if (theme)
|
||||||
|
return theme;
|
||||||
|
|
||||||
xdg_data_dirs = g_get_system_data_dirs ();
|
xdg_data_dirs = g_get_system_data_dirs ();
|
||||||
for (i = 0; xdg_data_dirs[i]; i++)
|
for (i = 0; xdg_data_dirs[i]; i++)
|
||||||
{
|
{
|
||||||
char *path = g_build_filename (xdg_data_dirs[i], "icons", name, "cursors", NULL);
|
theme = try_load_theme (display_wayland, xdg_data_dirs[i], FALSE, name, size);
|
||||||
|
|
||||||
if (g_file_test (path, G_FILE_TEST_IS_DIR))
|
|
||||||
theme = wl_cursor_theme_create (path, size, display_wayland->shm);
|
|
||||||
|
|
||||||
g_free (path);
|
|
||||||
|
|
||||||
if (theme)
|
if (theme)
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
@@ -1648,6 +1670,7 @@ static TranslationEntry translations[] = {
|
|||||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
||||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
||||||
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } },
|
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } },
|
||||||
|
/* Note, this setting doesn't exist, the portal and gsd fake it */
|
||||||
{ FALSE, "org.gnome.fontconfig", "serial", "gtk-fontconfig-timestamp", G_TYPE_NONE, { .i = 0 } },
|
{ FALSE, "org.gnome.fontconfig", "serial", "gtk-fontconfig-timestamp", G_TYPE_NONE, { .i = 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -153,14 +153,12 @@ struct _GdkWaylandDisplay
|
|||||||
|
|
||||||
/* egl info */
|
/* egl info */
|
||||||
EGLDisplay egl_display;
|
EGLDisplay egl_display;
|
||||||
|
EGLConfig egl_config;
|
||||||
int egl_major_version;
|
int egl_major_version;
|
||||||
int egl_minor_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_buffer_age : 1;
|
||||||
guint have_egl_swap_buffers_with_damage : 1;
|
guint have_egl_swap_buffers_with_damage : 1;
|
||||||
guint have_egl_surfaceless_context : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWaylandDisplayClass
|
struct _GdkWaylandDisplayClass
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ gdk_wayland_drag_cancel (GdkDrag *drag,
|
|||||||
GdkDragCancelReason reason)
|
GdkDragCancelReason reason)
|
||||||
{
|
{
|
||||||
gdk_drag_set_cursor (drag, NULL);
|
gdk_drag_set_cursor (drag, NULL);
|
||||||
|
gdk_drag_drop_done (drag, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -290,6 +291,7 @@ data_source_dnd_finished (void *data,
|
|||||||
GdkDrag *drag = data;
|
GdkDrag *drag = data;
|
||||||
|
|
||||||
g_signal_emit_by_name (drag, "dnd-finished");
|
g_signal_emit_by_name (drag, "dnd-finished");
|
||||||
|
gdk_drag_drop_done (drag, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
+166
-162
@@ -22,7 +22,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "gdkglcontext-wayland.h"
|
#include "gdkglcontext-wayland.h"
|
||||||
|
|
||||||
#include "gdkdisplay-wayland.h"
|
#include "gdkdisplay-wayland.h"
|
||||||
|
#include "gdksurface-wayland.h"
|
||||||
|
|
||||||
#include "gdkwaylanddisplay.h"
|
#include "gdkwaylanddisplay.h"
|
||||||
#include "gdkwaylandglcontext.h"
|
#include "gdkwaylandglcontext.h"
|
||||||
@@ -53,14 +55,14 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
|||||||
{
|
{
|
||||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||||
GdkGLContext *share = gdk_gl_context_get_shared_context (context);
|
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||||
GdkGLContext *shared_data_context = gdk_surface_get_shared_data_gl_context (gdk_gl_context_get_surface (context));
|
|
||||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||||
EGLContext ctx;
|
EGLContext ctx;
|
||||||
EGLint context_attribs[N_EGL_ATTRS];
|
EGLint context_attribs[N_EGL_ATTRS];
|
||||||
int major, minor, flags;
|
int major, minor, flags;
|
||||||
gboolean debug_bit, forward_bit, legacy_bit, use_es;
|
gboolean debug_bit, forward_bit, legacy_bit, use_es;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||||
|
|
||||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||||
@@ -120,10 +122,9 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
|||||||
use_es ? "yes" : "no"));
|
use_es ? "yes" : "no"));
|
||||||
|
|
||||||
ctx = eglCreateContext (display_wayland->egl_display,
|
ctx = eglCreateContext (display_wayland->egl_display,
|
||||||
context_wayland->egl_config,
|
display_wayland->egl_config,
|
||||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
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);
|
context_attribs);
|
||||||
|
|
||||||
/* If context creation failed without the ES bit, let's try again with it */
|
/* 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,
|
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||||
g_message ("eglCreateContext failed, switching to OpenGL ES"));
|
g_message ("eglCreateContext failed, switching to OpenGL ES"));
|
||||||
ctx = eglCreateContext (display_wayland->egl_display,
|
ctx = eglCreateContext (display_wayland->egl_display,
|
||||||
context_wayland->egl_config,
|
display_wayland->egl_config,
|
||||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
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);
|
context_attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,10 +177,9 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
|
|||||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||||
g_message ("eglCreateContext failed, switching to legacy"));
|
g_message ("eglCreateContext failed, switching to legacy"));
|
||||||
ctx = eglCreateContext (display_wayland->egl_display,
|
ctx = eglCreateContext (display_wayland->egl_display,
|
||||||
context_wayland->egl_config,
|
display_wayland->egl_config,
|
||||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
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);
|
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_is_legacy (context, legacy_bit);
|
||||||
gdk_gl_context_set_use_es (context, use_es);
|
gdk_gl_context_set_use_es (context, use_es);
|
||||||
|
|
||||||
|
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,17 +214,8 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context)
|
|||||||
|
|
||||||
if (display_wayland->have_egl_buffer_age)
|
if (display_wayland->have_egl_buffer_age)
|
||||||
{
|
{
|
||||||
GdkGLContext *shared;
|
egl_surface = gdk_wayland_surface_get_egl_surface (surface);
|
||||||
GdkWaylandGLContext *shared_wayland;
|
gdk_gl_context_make_current (context);
|
||||||
|
|
||||||
shared = gdk_gl_context_get_shared_context (context);
|
|
||||||
if (shared == NULL)
|
|
||||||
shared = context;
|
|
||||||
shared_wayland = GDK_WAYLAND_GL_CONTEXT (shared);
|
|
||||||
|
|
||||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface,
|
|
||||||
shared_wayland->egl_config);
|
|
||||||
gdk_gl_context_make_current (shared);
|
|
||||||
eglQuerySurface (display_wayland->egl_display, egl_surface,
|
eglQuerySurface (display_wayland->egl_display, egl_surface,
|
||||||
EGL_BUFFER_AGE_EXT, &buffer_age);
|
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);
|
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
|
static void
|
||||||
gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||||
cairo_region_t *painted)
|
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);
|
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
|
|
||||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
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);
|
gdk_gl_context_make_current (context);
|
||||||
|
|
||||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface,
|
egl_surface = gdk_wayland_surface_get_egl_surface (surface);
|
||||||
context_wayland->egl_config);
|
|
||||||
|
|
||||||
gdk_wayland_surface_sync (surface);
|
gdk_wayland_surface_sync (surface);
|
||||||
gdk_wayland_surface_request_frame (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;
|
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;
|
draw_context_class->end_frame = gdk_wayland_gl_context_end_frame;
|
||||||
|
|
||||||
context_class->realize = gdk_wayland_gl_context_realize;
|
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;
|
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.
|
* Retrieves the EGL display connection object for the given GDK display.
|
||||||
*
|
*
|
||||||
* Returns: (nullable): the EGL display
|
* Returns: (nullable): the EGL display
|
||||||
|
*
|
||||||
|
* Since: 4.4
|
||||||
*/
|
*/
|
||||||
gpointer
|
gpointer
|
||||||
gdk_wayland_display_get_egl_display (GdkDisplay *display)
|
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);
|
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;
|
return NULL;
|
||||||
|
|
||||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||||
@@ -393,71 +426,11 @@ out:
|
|||||||
return dpy;
|
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
|
#define MAX_EGL_ATTRS 30
|
||||||
|
|
||||||
static gboolean
|
static EGLConfig
|
||||||
find_eglconfig_for_surface (GdkSurface *surface,
|
get_eglconfig (EGLDisplay dpy)
|
||||||
EGLConfig *egl_config_out,
|
|
||||||
GError **error)
|
|
||||||
{
|
{
|
||||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
|
||||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
|
||||||
EGLint attrs[MAX_EGL_ATTRS];
|
EGLint attrs[MAX_EGL_ATTRS];
|
||||||
EGLint count;
|
EGLint count;
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
@@ -482,59 +455,129 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
|||||||
g_assert (i < MAX_EGL_ATTRS);
|
g_assert (i < MAX_EGL_ATTRS);
|
||||||
|
|
||||||
/* Pick first valid configuration i guess? */
|
/* Pick first valid configuration i guess? */
|
||||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, &config, 1, &count) || count < 1)
|
if (!eglChooseConfig (dpy, attrs, &config, 1, &count) || count < 1)
|
||||||
{
|
return NULL;
|
||||||
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);
|
return config;
|
||||||
*egl_config_out = config;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkGLContext *
|
#undef MAX_EGL_ATTRS
|
||||||
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;
|
|
||||||
|
|
||||||
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,
|
g_set_error_literal (error, GDK_GL_ERROR,
|
||||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||||
_("No GL implementation is available"));
|
_("No GL implementation is available"));
|
||||||
return NULL;
|
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,
|
g_set_error_literal (error, GDK_GL_ERROR,
|
||||||
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
|
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
|
||||||
_("Core GL is not available on EGL implementation"));
|
_("Core GL is not available on EGL implementation"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!find_eglconfig_for_surface (surface, &config, error))
|
if (!epoxy_has_egl_extension (dpy, "EGL_KHR_surfaceless_context"))
|
||||||
return NULL;
|
{
|
||||||
|
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,
|
start_time2 = GDK_PROFILER_CURRENT_TIME;
|
||||||
"surface", surface,
|
display_wayland->egl_config = get_eglconfig (dpy);
|
||||||
"shared-context", share,
|
gdk_profiler_end_mark (start_time2, "get_eglconfig", NULL);
|
||||||
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;
|
display_wayland->egl_display = dpy;
|
||||||
context->is_attached = attached;
|
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
|
static void
|
||||||
@@ -563,42 +606,3 @@ gdk_wayland_gl_context_dispose (GObject *gobject)
|
|||||||
G_OBJECT_CLASS (gdk_wayland_gl_context_parent_class)->dispose (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;
|
GdkGLContext parent_instance;
|
||||||
|
|
||||||
EGLContext egl_context;
|
EGLContext egl_context;
|
||||||
EGLConfig egl_config;
|
|
||||||
gboolean is_attached;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWaylandGLContextClass
|
struct _GdkWaylandGLContextClass
|
||||||
@@ -45,13 +43,8 @@ struct _GdkWaylandGLContextClass
|
|||||||
GdkGLContextClass parent_class;
|
GdkGLContextClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean gdk_wayland_display_init_gl (GdkDisplay *display);
|
GdkGLContext * gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||||
GdkGLContext * gdk_wayland_surface_create_gl_context (GdkSurface *surface,
|
|
||||||
gboolean attach,
|
|
||||||
GdkGLContext *share,
|
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
|
||||||
GdkGLContext *context);
|
|
||||||
|
|
||||||
G_END_DECLS
|
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);
|
struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface);
|
||||||
gboolean _gdk_wayland_is_shm_surface (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);
|
struct gtk_surface1 * gdk_wayland_surface_get_gtk_surface (GdkSurface *surface);
|
||||||
|
|
||||||
void gdk_wayland_seat_set_global_cursor (GdkSeat *seat,
|
void gdk_wayland_seat_set_global_cursor (GdkSeat *seat,
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ struct _GdkWaylandSurface
|
|||||||
|
|
||||||
struct gtk_surface1 *gtk_surface;
|
struct gtk_surface1 *gtk_surface;
|
||||||
struct wl_egl_window *egl_window;
|
struct wl_egl_window *egl_window;
|
||||||
struct wl_egl_window *dummy_egl_window;
|
|
||||||
struct zxdg_exported_v1 *xdg_exported;
|
struct zxdg_exported_v1 *xdg_exported;
|
||||||
struct org_kde_kwin_server_decoration *server_decoration;
|
struct org_kde_kwin_server_decoration *server_decoration;
|
||||||
} display_server;
|
} display_server;
|
||||||
@@ -111,7 +110,6 @@ struct _GdkWaylandSurface
|
|||||||
struct wl_event_queue *event_queue;
|
struct wl_event_queue *event_queue;
|
||||||
|
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
EGLSurface dummy_egl_surface;
|
|
||||||
|
|
||||||
uint32_t reposition_token;
|
uint32_t reposition_token;
|
||||||
uint32_t received_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->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)
|
if (impl->egl_surface)
|
||||||
{
|
{
|
||||||
eglDestroySurface (display_wayland->egl_display, 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->drag_begin = _gdk_wayland_surface_drag_begin;
|
||||||
impl_class->get_scale_factor = gdk_wayland_surface_get_scale_factor;
|
impl_class->get_scale_factor = gdk_wayland_surface_get_scale_factor;
|
||||||
impl_class->set_opaque_region = gdk_wayland_surface_set_opaque_region;
|
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->request_layout = gdk_wayland_surface_request_layout;
|
||||||
impl_class->compute_size = gdk_wayland_surface_compute_size;
|
impl_class->compute_size = gdk_wayland_surface_compute_size;
|
||||||
}
|
}
|
||||||
@@ -4304,8 +4289,7 @@ gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EGLSurface
|
EGLSurface
|
||||||
gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
|
gdk_wayland_surface_get_egl_surface (GdkSurface *surface)
|
||||||
EGLConfig config)
|
|
||||||
{
|
{
|
||||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||||
GdkWaylandSurface *impl;
|
GdkWaylandSurface *impl;
|
||||||
@@ -4320,35 +4304,12 @@ gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
|
|||||||
egl_window = gdk_wayland_surface_get_wl_egl_window (surface);
|
egl_window = gdk_wayland_surface_get_wl_egl_window (surface);
|
||||||
|
|
||||||
impl->egl_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;
|
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 *
|
struct gtk_surface1 *
|
||||||
gdk_wayland_surface_get_gtk_surface (GdkSurface *surface)
|
gdk_wayland_surface_get_gtk_surface (GdkSurface *surface)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
#include "gdkwaylandsurface.h"
|
#include "gdkwaylandsurface.h"
|
||||||
|
|
||||||
|
#include <wayland-egl.h>
|
||||||
|
#include <epoxy/egl.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel,
|
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);
|
gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel);
|
||||||
void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel);
|
void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel);
|
||||||
|
|
||||||
|
EGLSurface gdk_wayland_surface_get_egl_surface (GdkSurface *surface);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
+138
-58
@@ -481,6 +481,7 @@ register_display_change_notification (GdkDisplay *display)
|
|||||||
wclass.lpszClassName = "GdkDisplayChange";
|
wclass.lpszClassName = "GdkDisplayChange";
|
||||||
wclass.lpfnWndProc = display_change_window_procedure;
|
wclass.lpfnWndProc = display_change_window_procedure;
|
||||||
wclass.hInstance = _gdk_app_hmodule;
|
wclass.hInstance = _gdk_app_hmodule;
|
||||||
|
wclass.style = CS_OWNDC;
|
||||||
|
|
||||||
klass = RegisterClass (&wclass);
|
klass = RegisterClass (&wclass);
|
||||||
if (klass)
|
if (klass)
|
||||||
@@ -656,6 +657,13 @@ gdk_win32_display_dispose (GObject *object)
|
|||||||
|
|
||||||
if (display_win32->hwnd != NULL)
|
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);
|
DestroyWindow (display_win32->hwnd);
|
||||||
display_win32->hwnd = NULL;
|
display_win32->hwnd = NULL;
|
||||||
}
|
}
|
||||||
@@ -982,31 +990,32 @@ _gdk_win32_check_on_arm64 (GdkWin32Display *display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_win32_display_init (GdkWin32Display *display)
|
gdk_win32_display_init (GdkWin32Display *display_win32)
|
||||||
{
|
{
|
||||||
const char *scale_str = g_getenv ("GDK_SCALE");
|
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_enable_hidpi (display_win32);
|
||||||
_gdk_win32_check_on_arm64 (display);
|
_gdk_win32_check_on_arm64 (display_win32);
|
||||||
|
|
||||||
/* if we have DPI awareness, set up fixed scale if set */
|
/* 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)
|
scale_str != NULL)
|
||||||
{
|
{
|
||||||
display->surface_scale = atol (scale_str);
|
display_win32->surface_scale = atol (scale_str);
|
||||||
|
|
||||||
if (display->surface_scale <= 0)
|
if (display_win32->surface_scale <= 0)
|
||||||
display->surface_scale = 1;
|
display_win32->surface_scale = 1;
|
||||||
|
|
||||||
display->has_fixed_scale = TRUE;
|
display_win32->has_fixed_scale = TRUE;
|
||||||
}
|
}
|
||||||
else
|
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_init_cursors (display_win32);
|
||||||
gdk_win32_display_check_composited (display);
|
gdk_win32_display_check_composited (display_win32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1057,64 +1066,64 @@ gdk_win32_display_get_monitors (GdkDisplay *display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
guint
|
guint
|
||||||
_gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||||
HMONITOR hmonitor,
|
GdkSurface *surface,
|
||||||
HWND hwnd,
|
HMONITOR hmonitor)
|
||||||
int *dpi)
|
|
||||||
{
|
{
|
||||||
gboolean is_scale_acquired = FALSE;
|
gboolean is_scale_acquired = FALSE;
|
||||||
gboolean use_dpi_for_monitor = FALSE;
|
gboolean use_dpi_for_monitor = FALSE;
|
||||||
guint dpix, dpiy;
|
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;
|
use_dpi_for_monitor = TRUE;
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hwnd != NULL)
|
|
||||||
{
|
|
||||||
hmonitor = MonitorFromWindow (hwnd, MONITOR_DEFAULTTONEAREST);
|
|
||||||
use_dpi_for_monitor = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_dpi_for_monitor)
|
if (use_dpi_for_monitor)
|
||||||
{
|
{
|
||||||
/* Use GetDpiForMonitor() for Windows 8.1+, when we have a HMONITOR */
|
/* Use GetDpiForMonitor() for Windows 8.1+, when we have a HMONITOR */
|
||||||
if (win32_display->shcore_funcs.hshcore != NULL &&
|
if (display_win32->shcore_funcs.getDpiForMonitorFunc (hmonitor,
|
||||||
win32_display->shcore_funcs.getDpiForMonitorFunc != NULL)
|
MDT_EFFECTIVE_DPI,
|
||||||
{
|
&dpix,
|
||||||
if (win32_display->shcore_funcs.getDpiForMonitorFunc (hmonitor,
|
&dpiy) == S_OK)
|
||||||
MDT_EFFECTIVE_DPI,
|
is_scale_acquired = TRUE;
|
||||||
&dpix,
|
|
||||||
&dpiy) == S_OK)
|
|
||||||
{
|
|
||||||
is_scale_acquired = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Go back to GetDeviceCaps() for Windows 8 and earlier, or when we don't
|
/* Go back to GetDeviceCaps() for Windows 8 and earlier, or when we don't
|
||||||
* have a HMONITOR nor a HWND
|
* 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 */
|
/* in case we can't get the DC for the window, return 1 for the scale */
|
||||||
if (hdc == NULL)
|
if (hdc == NULL)
|
||||||
{
|
return 1;
|
||||||
if (dpi != NULL)
|
|
||||||
*dpi = USER_DEFAULT_SCREEN_DPI;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dpix = GetDeviceCaps (hdc, LOGPIXELSX);
|
dpix = GetDeviceCaps (hdc, LOGPIXELSX);
|
||||||
dpiy = GetDeviceCaps (hdc, LOGPIXELSY);
|
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;
|
is_scale_acquired = TRUE;
|
||||||
}
|
}
|
||||||
@@ -1122,21 +1131,13 @@ _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
|||||||
if (is_scale_acquired)
|
if (is_scale_acquired)
|
||||||
/* USER_DEFAULT_SCREEN_DPI = 96, in winuser.h */
|
/* USER_DEFAULT_SCREEN_DPI = 96, in winuser.h */
|
||||||
{
|
{
|
||||||
if (dpi != NULL)
|
if (display_win32->has_fixed_scale)
|
||||||
*dpi = dpix;
|
return display_win32->surface_scale;
|
||||||
|
|
||||||
if (win32_display->has_fixed_scale)
|
|
||||||
return win32_display->surface_scale;
|
|
||||||
else
|
else
|
||||||
return dpix / USER_DEFAULT_SCREEN_DPI > 1 ? dpix / USER_DEFAULT_SCREEN_DPI : 1;
|
return dpix / USER_DEFAULT_SCREEN_DPI > 1 ? dpix / USER_DEFAULT_SCREEN_DPI : 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return 1;
|
||||||
if (dpi != NULL)
|
|
||||||
*dpi = USER_DEFAULT_SCREEN_DPI;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -1147,6 +1148,85 @@ gdk_win32_display_get_setting (GdkDisplay *display,
|
|||||||
return _gdk_win32_get_setting (name, value);
|
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
|
static void
|
||||||
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||||
{
|
{
|
||||||
@@ -1172,7 +1252,6 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
|||||||
display_class->create_surface = _gdk_win32_display_create_surface;
|
display_class->create_surface = _gdk_win32_display_create_surface;
|
||||||
|
|
||||||
display_class->get_keymap = _gdk_win32_display_get_keymap;
|
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;
|
display_class->get_monitors = gdk_win32_display_get_monitors;
|
||||||
|
|
||||||
@@ -1183,6 +1262,7 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
|||||||
|
|
||||||
display_class->get_setting = gdk_win32_display_get_setting;
|
display_class->get_setting = gdk_win32_display_get_setting;
|
||||||
display_class->set_cursor_theme = gdk_win32_display_set_cursor_theme;
|
display_class->set_cursor_theme = gdk_win32_display_set_cursor_theme;
|
||||||
|
display_class->init_gl = gdk_win32_display_init_gl;
|
||||||
|
|
||||||
_gdk_win32_surfaceing_init ();
|
_gdk_win32_surfaceing_init ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,12 @@ typedef struct _GdkWin32KernelCPUFuncs
|
|||||||
funcIsWow64Process2 isWow64Process2;
|
funcIsWow64Process2 isWow64Process2;
|
||||||
} GdkWin32KernelCPUFuncs;
|
} GdkWin32KernelCPUFuncs;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
HDC hdc;
|
||||||
|
HGLRC hglrc;
|
||||||
|
} GdkWin32GLDummyContextWGL;
|
||||||
|
|
||||||
struct _GdkWin32Display
|
struct _GdkWin32Display
|
||||||
{
|
{
|
||||||
GdkDisplay display;
|
GdkDisplay display;
|
||||||
@@ -119,15 +125,15 @@ struct _GdkWin32Display
|
|||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
|
||||||
/* WGL/OpenGL Items */
|
/* WGL/OpenGL Items */
|
||||||
guint have_wgl : 1;
|
GdkWin32GLDummyContextWGL dummy_context_wgl;
|
||||||
|
int wgl_pixel_format;
|
||||||
guint gl_version;
|
guint gl_version;
|
||||||
HWND gl_hwnd;
|
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef GDK_WIN32_ENABLE_EGL
|
||||||
/* EGL (Angle) Items */
|
/* EGL (Angle) Items */
|
||||||
guint have_egl : 1;
|
|
||||||
guint egl_version;
|
guint egl_version;
|
||||||
EGLDisplay egl_disp;
|
EGLDisplay egl_disp;
|
||||||
|
EGLConfig egl_config;
|
||||||
HDC hdc_egl_temp;
|
HDC hdc_egl_temp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -185,10 +191,9 @@ GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
|
|||||||
|
|
||||||
void gdk_win32_display_check_composited (GdkWin32Display *display);
|
void gdk_win32_display_check_composited (GdkWin32Display *display);
|
||||||
|
|
||||||
guint _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
|
guint gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *display_win32,
|
||||||
HMONITOR hmonitor,
|
GdkSurface *surface,
|
||||||
HWND hwnd,
|
HMONITOR hmonitor);
|
||||||
int *dpi);
|
|
||||||
|
|
||||||
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
|
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
|
||||||
|
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ gdk_drag_new (GdkDisplay *display,
|
|||||||
GdkDragProtocol protocol)
|
GdkDragProtocol protocol)
|
||||||
{
|
{
|
||||||
GdkWin32Drag *drag_win32;
|
GdkWin32Drag *drag_win32;
|
||||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||||
GdkDrag *drag;
|
GdkDrag *drag;
|
||||||
|
|
||||||
drag_win32 = g_object_new (GDK_TYPE_WIN32_DRAG,
|
drag_win32 = g_object_new (GDK_TYPE_WIN32_DRAG,
|
||||||
@@ -805,10 +805,10 @@ gdk_drag_new (GdkDisplay *display,
|
|||||||
|
|
||||||
drag = GDK_DRAG (drag_win32);
|
drag = GDK_DRAG (drag_win32);
|
||||||
|
|
||||||
if (win32_display->has_fixed_scale)
|
if (display_win32->has_fixed_scale)
|
||||||
drag_win32->scale = win32_display->surface_scale;
|
drag_win32->scale = display_win32->surface_scale;
|
||||||
else
|
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;
|
drag_win32->protocol = protocol;
|
||||||
|
|
||||||
@@ -2345,8 +2345,8 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
|
|||||||
state = gdk_event_get_modifier_state (event);
|
state = gdk_event_get_modifier_state (event);
|
||||||
gdk_event_get_position (event, &x, &y);
|
gdk_event_get_position (event, &x, &y);
|
||||||
|
|
||||||
x_root = x + _gdk_offset_x;
|
x_root = event->surface->x + x;
|
||||||
y_root = y + _gdk_offset_y;
|
y_root = event->surface->y + y;
|
||||||
|
|
||||||
if (drag_win32->drag_surface)
|
if (drag_win32->drag_surface)
|
||||||
move_drag_surface (drag, x_root, y_root);
|
move_drag_surface (drag, x_root, y_root);
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ gdk_drop_new (GdkDisplay *display,
|
|||||||
GdkDragProtocol protocol)
|
GdkDragProtocol protocol)
|
||||||
{
|
{
|
||||||
GdkWin32Drop *drop_win32;
|
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,
|
drop_win32 = g_object_new (GDK_TYPE_WIN32_DROP,
|
||||||
"device", device,
|
"device", device,
|
||||||
@@ -186,10 +186,10 @@ gdk_drop_new (GdkDisplay *display,
|
|||||||
"surface", surface,
|
"surface", surface,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (win32_display->has_fixed_scale)
|
if (display_win32->has_fixed_scale)
|
||||||
drop_win32->scale = win32_display->surface_scale;
|
drop_win32->scale = display_win32->surface_scale;
|
||||||
else
|
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;
|
drop_win32->protocol = protocol;
|
||||||
|
|
||||||
|
|||||||
@@ -2343,7 +2343,6 @@ gdk_event_translate (MSG *msg,
|
|||||||
current_root_x = (msg->pt.x + _gdk_offset_x) / impl->surface_scale;
|
current_root_x = (msg->pt.x + _gdk_offset_x) / impl->surface_scale;
|
||||||
current_root_y = (msg->pt.y + _gdk_offset_y) / impl->surface_scale;
|
current_root_y = (msg->pt.y + _gdk_offset_y) / impl->surface_scale;
|
||||||
|
|
||||||
|
|
||||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||||
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||||
else if (_gdk_input_ignore_core == 0)
|
else if (_gdk_input_ignore_core == 0)
|
||||||
|
|||||||
@@ -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
|
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
|
struct _GdkWin32GLContext
|
||||||
{
|
{
|
||||||
GdkGLContext parent_instance;
|
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
|
struct _GdkWin32GLContextClass
|
||||||
@@ -60,15 +49,33 @@ struct _GdkWin32GLContextClass
|
|||||||
GdkGLContextClass parent_class;
|
GdkGLContextClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GdkGLContext *
|
/* WGL */
|
||||||
_gdk_win32_surface_create_gl_context (GdkSurface *window,
|
#define GDK_TYPE_WIN32_GL_CONTEXT_WGL (gdk_win32_gl_context_wgl_get_type())
|
||||||
gboolean attached,
|
#define GDK_WIN32_GL_CONTEXT_WGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL, GdkWin32GLContextWGL))
|
||||||
GdkGLContext *share,
|
#define GDK_IS_WIN32_GL_CONTEXT_WGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WIN32_GL_CONTEXT_WGL))
|
||||||
GError **error);
|
|
||||||
|
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
|
void
|
||||||
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface);
|
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface);
|
||||||
|
|
||||||
|
|||||||
@@ -694,6 +694,7 @@ update_keymap (GdkKeymap *gdk_keymap)
|
|||||||
if (hkls_len != keymap->layout_handles->len)
|
if (hkls_len != keymap->layout_handles->len)
|
||||||
keymap->keysym_tab = g_renew (guint, keymap->keysym_tab, keysym_tab_size);
|
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);
|
memset (keymap->keysym_tab, 0, keysym_tab_size);
|
||||||
g_array_set_size (keymap->layout_handles, hkls_len);
|
g_array_set_size (keymap->layout_handles, hkls_len);
|
||||||
g_array_set_size (keymap->options, hkls_len);
|
g_array_set_size (keymap->options, hkls_len);
|
||||||
|
|||||||
@@ -681,7 +681,7 @@ enum_monitor (HMONITOR hmonitor,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* First acquire the scale using the current screen */
|
/* 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+ */
|
/* acquire the scale using the monitor which the window is nearest on Windows 8.1+ */
|
||||||
if (data->display->have_at_least_win81)
|
if (data->display->have_at_least_win81)
|
||||||
@@ -695,7 +695,7 @@ enum_monitor (HMONITOR hmonitor,
|
|||||||
pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2;
|
pt.x = w32mon->work_rect.x + w32mon->work_rect.width / 2;
|
||||||
pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2;
|
pt.y = w32mon->work_rect.y + w32mon->work_rect.height / 2;
|
||||||
hmonitor = MonitorFromPoint (pt, MONITOR_DEFAULTTONEAREST);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,8 +78,7 @@ init_root_window (GdkWin32Screen *screen_win32)
|
|||||||
win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
win32_display = GDK_WIN32_DISPLAY (_gdk_display);
|
||||||
|
|
||||||
if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
|
if (win32_display->dpi_aware_type != PROCESS_DPI_UNAWARE)
|
||||||
screen_win32->surface_scale = _gdk_win32_display_get_monitor_scale_factor (win32_display,
|
screen_win32->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||||
NULL,
|
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -352,12 +352,14 @@ RegisterGdkClass (GdkSurfaceType wtype)
|
|||||||
{
|
{
|
||||||
char sLoc [MAX_PATH+1];
|
char sLoc [MAX_PATH+1];
|
||||||
|
|
||||||
if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
|
// try to load first icon of executable program
|
||||||
|
if (0 != GetModuleFileName (NULL, sLoc, MAX_PATH))
|
||||||
{
|
{
|
||||||
ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
|
ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
|
||||||
|
|
||||||
if (0 == hAppIcon && 0 == hAppIconSm)
|
if (0 == hAppIcon && 0 == hAppIconSm)
|
||||||
{
|
{
|
||||||
|
// fallback : load icon from GTK DLL
|
||||||
if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
|
if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
|
||||||
{
|
{
|
||||||
ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
|
ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
|
||||||
@@ -395,12 +397,13 @@ RegisterGdkClass (GdkSurfaceType wtype)
|
|||||||
wcl.hbrBackground = NULL; \
|
wcl.hbrBackground = NULL; \
|
||||||
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
|
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||||
|
|
||||||
|
/* MSDN: CS_OWNDC is needed for OpenGL contexts */
|
||||||
|
wcl.style |= CS_OWNDC;
|
||||||
|
|
||||||
switch (wtype)
|
switch (wtype)
|
||||||
{
|
{
|
||||||
case GDK_SURFACE_TOPLEVEL:
|
case GDK_SURFACE_TOPLEVEL:
|
||||||
case GDK_SURFACE_POPUP:
|
case GDK_SURFACE_POPUP:
|
||||||
/* MSDN: CS_OWNDC is needed for OpenGL contexts */
|
|
||||||
wcl.style |= CS_OWNDC;
|
|
||||||
if (0 == klassTOPLEVEL)
|
if (0 == klassTOPLEVEL)
|
||||||
{
|
{
|
||||||
wcl.lpszClassName = L"gdkSurfaceToplevel";
|
wcl.lpszClassName = L"gdkSurfaceToplevel";
|
||||||
@@ -519,7 +522,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
|||||||
surface->width = width;
|
surface->width = width;
|
||||||
surface->height = height;
|
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;
|
dwExStyle = 0;
|
||||||
owner = NULL;
|
owner = NULL;
|
||||||
@@ -652,6 +655,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
|||||||
impl);
|
impl);
|
||||||
|
|
||||||
g_object_unref (frame_clock);
|
g_object_unref (frame_clock);
|
||||||
|
impl->hdc = GetDC (impl->handle);
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
@@ -1227,6 +1231,7 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
|||||||
&shadow_right,
|
&shadow_right,
|
||||||
&shadow_top,
|
&shadow_top,
|
||||||
&shadow_bottom);
|
&shadow_bottom);
|
||||||
|
|
||||||
gdk_win32_surface_set_shadow_width (surface,
|
gdk_win32_surface_set_shadow_width (surface,
|
||||||
shadow_left,
|
shadow_left,
|
||||||
shadow_right,
|
shadow_right,
|
||||||
@@ -1236,10 +1241,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
|||||||
gdk_surface_layout_popup_helper (surface,
|
gdk_surface_layout_popup_helper (surface,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
impl->shadow.left,
|
shadow_left,
|
||||||
impl->shadow.right,
|
shadow_right,
|
||||||
impl->shadow.top,
|
shadow_top,
|
||||||
impl->shadow.bottom,
|
shadow_bottom,
|
||||||
monitor,
|
monitor,
|
||||||
&bounds,
|
&bounds,
|
||||||
layout,
|
layout,
|
||||||
@@ -1259,9 +1264,7 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
|||||||
final_rect.height);
|
final_rect.height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
gdk_win32_surface_move (surface, x, y);
|
||||||
gdk_win32_surface_move (surface, x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4415,9 +4418,9 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
|
|||||||
if (impl->zero_shadow)
|
if (impl->zero_shadow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
impl->shadow.left = left;
|
impl->shadow.left = left * impl->surface_scale;;
|
||||||
impl->shadow.right = right * impl->surface_scale;
|
impl->shadow.right = right * impl->surface_scale;
|
||||||
impl->shadow.top = top;
|
impl->shadow.top = top * impl->surface_scale;;
|
||||||
impl->shadow.bottom = bottom * impl->surface_scale;
|
impl->shadow.bottom = bottom * impl->surface_scale;
|
||||||
impl->shadow_x = left + right;
|
impl->shadow_x = left + right;
|
||||||
impl->shadow_y = top + bottom;
|
impl->shadow_y = top + bottom;
|
||||||
@@ -4425,19 +4428,19 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_gdk_win32_surface_get_scale_factor (GdkSurface *window)
|
_gdk_win32_surface_get_scale_factor (GdkSurface *surface)
|
||||||
{
|
{
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
GdkWin32Surface *impl;
|
GdkWin32Surface *impl;
|
||||||
GdkWin32Display *win32_display;
|
GdkWin32Display *win32_display;
|
||||||
|
|
||||||
if (GDK_SURFACE_DESTROYED (window))
|
if (GDK_SURFACE_DESTROYED (surface))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
g_return_val_if_fail (window != NULL, 1);
|
g_return_val_if_fail (surface != NULL, 1);
|
||||||
|
|
||||||
display = gdk_surface_get_display (window);
|
display = gdk_surface_get_display (surface);
|
||||||
impl = GDK_WIN32_SURFACE (window);
|
impl = GDK_WIN32_SURFACE (surface);
|
||||||
|
|
||||||
win32_display = GDK_WIN32_DISPLAY (display);
|
win32_display = GDK_WIN32_DISPLAY (display);
|
||||||
|
|
||||||
@@ -4446,9 +4449,8 @@ _gdk_win32_surface_get_scale_factor (GdkSurface *window)
|
|||||||
if (win32_display->has_fixed_scale)
|
if (win32_display->has_fixed_scale)
|
||||||
impl->surface_scale = win32_display->surface_scale;
|
impl->surface_scale = win32_display->surface_scale;
|
||||||
else
|
else
|
||||||
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (win32_display,
|
impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (win32_display,
|
||||||
NULL,
|
surface,
|
||||||
GDK_SURFACE_HWND (window),
|
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return impl->surface_scale;
|
return impl->surface_scale;
|
||||||
@@ -4553,7 +4555,7 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
|
|||||||
int scale = impl->surface_scale;
|
int scale = impl->surface_scale;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
|
||||||
if (GDK_IS_TOPLEVEL (surface) && impl->drag_move_resize_context.native_move_resize_pending)
|
if (impl->drag_move_resize_context.native_move_resize_pending)
|
||||||
{
|
{
|
||||||
surface->width = impl->next_layout.configured_width;
|
surface->width = impl->next_layout.configured_width;
|
||||||
surface->height = impl->next_layout.configured_height;
|
surface->height = impl->next_layout.configured_height;
|
||||||
@@ -4564,8 +4566,18 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
|
|||||||
|
|
||||||
impl->next_layout.configured_width = (rect.right - rect.left + scale - 1) / scale;
|
impl->next_layout.configured_width = (rect.right - rect.left + scale - 1) / scale;
|
||||||
impl->next_layout.configured_height = (rect.bottom - rect.top + scale - 1) / scale;
|
impl->next_layout.configured_height = (rect.bottom - rect.top + scale - 1) / scale;
|
||||||
surface->x = rect.left / scale;
|
|
||||||
surface->y = rect.top / scale;
|
if (GDK_IS_TOPLEVEL (surface))
|
||||||
|
{
|
||||||
|
surface->x = rect.left / scale;
|
||||||
|
surface->y = rect.top / scale;
|
||||||
|
}
|
||||||
|
else if (GDK_IS_POPUP (surface))
|
||||||
|
{
|
||||||
|
gdk_win32_surface_get_geometry (surface,
|
||||||
|
&surface->x, &surface->y,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4612,7 +4624,6 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
|||||||
|
|
||||||
impl_class->destroy_notify = gdk_win32_surface_destroy_notify;
|
impl_class->destroy_notify = gdk_win32_surface_destroy_notify;
|
||||||
impl_class->drag_begin = _gdk_win32_surface_drag_begin;
|
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->get_scale_factor = _gdk_win32_surface_get_scale_factor;
|
||||||
impl_class->request_layout = _gdk_win32_surface_request_layout;
|
impl_class->request_layout = _gdk_win32_surface_request_layout;
|
||||||
impl_class->compute_size = _gdk_win32_surface_compute_size;
|
impl_class->compute_size = _gdk_win32_surface_compute_size;
|
||||||
@@ -4655,9 +4666,9 @@ gdk_win32_popup_init (GdkWin32Popup *popup)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_win32_popup_get_property (GObject *object,
|
gdk_win32_popup_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GdkSurface *surface = GDK_SURFACE (object);
|
GdkSurface *surface = GDK_SURFACE (object);
|
||||||
|
|
||||||
@@ -4679,9 +4690,9 @@ gdk_win32_popup_get_property (GObject *object,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_win32_popup_set_property (GObject *object,
|
gdk_win32_popup_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
GdkSurface *surface = GDK_SURFACE (object);
|
GdkSurface *surface = GDK_SURFACE (object);
|
||||||
|
|
||||||
@@ -4716,9 +4727,9 @@ gdk_win32_popup_class_init (GdkWin32PopupClass *class)
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gdk_win32_popup_present (GdkPopup *popup,
|
gdk_win32_popup_present (GdkPopup *popup,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
GdkPopupLayout *layout)
|
GdkPopupLayout *layout)
|
||||||
{
|
{
|
||||||
return gdk_win32_surface_present_popup (GDK_SURFACE (popup), width, height, layout);
|
return gdk_win32_surface_present_popup (GDK_SURFACE (popup), width, height, layout);
|
||||||
}
|
}
|
||||||
@@ -5034,9 +5045,9 @@ gdk_win32_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
|
|||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef GDK_WIN32_ENABLE_EGL
|
||||||
EGLSurface
|
EGLSurface
|
||||||
_gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||||
EGLConfig config,
|
EGLConfig config,
|
||||||
gboolean is_dummy)
|
gboolean is_dummy)
|
||||||
{
|
{
|
||||||
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface));
|
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_surface_get_display (surface));
|
||||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||||
@@ -5055,7 +5066,10 @@ _gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (impl->egl_surface == EGL_NO_SURFACE)
|
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;
|
return impl->egl_surface;
|
||||||
}
|
}
|
||||||
@@ -5138,3 +5152,20 @@ gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
|
|||||||
|
|
||||||
return queued_window_rect;
|
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);
|
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
|
||||||
|
|
||||||
#ifdef GDK_WIN32_ENABLE_EGL
|
#ifdef GDK_WIN32_ENABLE_EGL
|
||||||
EGLSurface _gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
EGLSurface gdk_win32_surface_get_egl_surface (GdkSurface *surface,
|
||||||
EGLConfig config,
|
EGLConfig config,
|
||||||
gboolean is_dummy);
|
gboolean is_dummy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ gdk_win32_sources = files([
|
|||||||
'gdkdrop-win32.c',
|
'gdkdrop-win32.c',
|
||||||
'gdkevents-win32.c',
|
'gdkevents-win32.c',
|
||||||
'gdkglcontext-win32.c',
|
'gdkglcontext-win32.c',
|
||||||
|
'gdkglcontext-win32-wgl.c',
|
||||||
'gdkglobals-win32.c',
|
'gdkglobals-win32.c',
|
||||||
'gdkhdataoutputstream-win32.c',
|
'gdkhdataoutputstream-win32.c',
|
||||||
'gdkkeys-win32.c',
|
'gdkkeys-win32.c',
|
||||||
@@ -47,6 +48,7 @@ GDK_WIN32_EGL_CFLAGS = []
|
|||||||
|
|
||||||
if win32_has_egl
|
if win32_has_egl
|
||||||
GDK_WIN32_EGL_CFLAGS = ['-DGDK_WIN32_ENABLE_EGL']
|
GDK_WIN32_EGL_CFLAGS = ['-DGDK_WIN32_ENABLE_EGL']
|
||||||
|
gdk_win32_sources += ['gdkglcontext-win32-egl.c']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
gdk_win32_deps = [ # FIXME
|
gdk_win32_deps = [ # FIXME
|
||||||
|
|||||||
+130
-101
@@ -69,10 +69,6 @@
|
|||||||
|
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
|
|
||||||
#ifdef HAVE_XCOMPOSITE
|
|
||||||
#include <X11/extensions/Xcomposite.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_RANDR
|
#ifdef HAVE_RANDR
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -1339,20 +1335,70 @@ set_sm_client_id (GdkDisplay *display,
|
|||||||
gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
|
gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
gdk_display_setup_window_visual (GdkDisplay *display,
|
gdk_x11_display_query_default_visual (GdkX11Display *self,
|
||||||
int depth,
|
Visual **out_visual,
|
||||||
Visual *visual,
|
int *out_depth)
|
||||||
Colormap colormap,
|
|
||||||
gboolean rgba)
|
|
||||||
{
|
{
|
||||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
XVisualInfo template, *visinfo;
|
||||||
|
int n_visuals;
|
||||||
|
Display *dpy;
|
||||||
|
|
||||||
display_x11->window_depth = depth;
|
dpy = gdk_x11_display_get_xdisplay (GDK_DISPLAY (self));
|
||||||
display_x11->window_visual = visual;
|
|
||||||
display_x11->window_colormap = colormap;
|
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
|
||||||
/* initialize the display's screens */
|
/* 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
|
/* If GL is available we want to pick better default/rgba visuals,
|
||||||
* structures in places
|
* 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));
|
if (!gdk_display_prepare_gl (display, NULL))
|
||||||
|
{
|
||||||
display_x11->device_manager = _gdk_x11_device_manager_new (display);
|
gdk_x11_display_query_default_visual (display_x11, &display_x11->window_visual, &display_x11->window_depth);
|
||||||
|
gdk_x11_display_init_leader_surface (display_x11);
|
||||||
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;
|
|
||||||
|
|
||||||
#ifdef HAVE_XFIXES
|
#ifdef HAVE_XFIXES
|
||||||
if (XFixesQueryExtension (display_x11->xdisplay,
|
if (XFixesQueryExtension (display_x11->xdisplay,
|
||||||
@@ -1454,24 +1492,6 @@ gdk_x11_display_open (const char *display_name)
|
|||||||
#endif
|
#endif
|
||||||
display_x11->have_xfixes = FALSE;
|
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_shapes = FALSE;
|
||||||
display_x11->have_input_shapes = FALSE;
|
display_x11->have_input_shapes = FALSE;
|
||||||
|
|
||||||
@@ -1928,7 +1948,6 @@ gdk_x11_display_finalize (GObject *object)
|
|||||||
|
|
||||||
/* Free all GdkX11Screens */
|
/* Free all GdkX11Screens */
|
||||||
g_object_unref (display_x11->screen);
|
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_list_store_remove_all (display_x11->monitors);
|
||||||
g_object_unref (display_x11->monitors);
|
g_object_unref (display_x11->monitors);
|
||||||
@@ -1940,6 +1959,8 @@ gdk_x11_display_finalize (GObject *object)
|
|||||||
|
|
||||||
XCloseDisplay (display_x11->xdisplay);
|
XCloseDisplay (display_x11->xdisplay);
|
||||||
|
|
||||||
|
g_clear_error (&display_x11->gl_error);
|
||||||
|
|
||||||
/* error traps */
|
/* error traps */
|
||||||
while (display_x11->error_traps != NULL)
|
while (display_x11->error_traps != NULL)
|
||||||
{
|
{
|
||||||
@@ -1993,52 +2014,6 @@ gdk_x11_lookup_xdisplay (Display *xdisplay)
|
|||||||
return display;
|
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:
|
* gdk_x11_display_get_xdisplay:
|
||||||
* @display: (type GdkX11Display): a `GdkDisplay`
|
* @display: (type GdkX11Display): a `GdkDisplay`
|
||||||
@@ -2910,6 +2885,60 @@ gdk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
|
|||||||
return continue_emission;
|
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
|
static void
|
||||||
gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
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->create_surface = _gdk_x11_display_create_surface;
|
||||||
display_class->get_keymap = gdk_x11_display_get_keymap;
|
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;
|
display_class->get_default_seat = gdk_x11_display_get_default_seat;
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ struct _GdkX11Display
|
|||||||
GdkDisplay parent_instance;
|
GdkDisplay parent_instance;
|
||||||
Display *xdisplay;
|
Display *xdisplay;
|
||||||
GdkX11Screen *screen;
|
GdkX11Screen *screen;
|
||||||
GList *screens;
|
|
||||||
GList *toplevels;
|
GList *toplevels;
|
||||||
GdkX11DeviceManagerXI2 *device_manager;
|
GdkX11DeviceManagerXI2 *device_manager;
|
||||||
|
|
||||||
@@ -71,8 +70,6 @@ struct _GdkX11Display
|
|||||||
gboolean have_xfixes;
|
gboolean have_xfixes;
|
||||||
int xfixes_event_base;
|
int xfixes_event_base;
|
||||||
|
|
||||||
gboolean have_xcomposite;
|
|
||||||
|
|
||||||
gboolean have_randr12;
|
gboolean have_randr12;
|
||||||
gboolean have_randr13;
|
gboolean have_randr13;
|
||||||
gboolean have_randr15;
|
gboolean have_randr15;
|
||||||
@@ -132,12 +129,17 @@ struct _GdkX11Display
|
|||||||
guint have_damage;
|
guint have_damage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* If GL is not supported, store the error here */
|
||||||
|
GError *gl_error;
|
||||||
|
|
||||||
/* GLX information */
|
/* GLX information */
|
||||||
|
/* GLXFBConfig */ gpointer glx_config;
|
||||||
int glx_version;
|
int glx_version;
|
||||||
int glx_error_base;
|
|
||||||
int glx_event_base;
|
|
||||||
|
|
||||||
/* EGL information */
|
/* 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;
|
int egl_version;
|
||||||
|
|
||||||
/* Translation between X server time and system-local monotonic time */
|
/* Translation between X server time and system-local monotonic time */
|
||||||
@@ -146,9 +148,6 @@ struct _GdkX11Display
|
|||||||
|
|
||||||
guint server_time_is_monotonic_time : 1;
|
guint server_time_is_monotonic_time : 1;
|
||||||
|
|
||||||
guint have_glx : 1;
|
|
||||||
guint have_egl : 1;
|
|
||||||
|
|
||||||
/* GLX extensions we check */
|
/* GLX extensions we check */
|
||||||
guint has_glx_swap_interval : 1;
|
guint has_glx_swap_interval : 1;
|
||||||
guint has_glx_create_context : 1;
|
guint has_glx_create_context : 1;
|
||||||
@@ -165,7 +164,6 @@ struct _GdkX11Display
|
|||||||
guint has_egl_khr_create_context : 1;
|
guint has_egl_khr_create_context : 1;
|
||||||
guint has_egl_buffer_age : 1;
|
guint has_egl_buffer_age : 1;
|
||||||
guint has_egl_swap_buffers_with_damage : 1;
|
guint has_egl_swap_buffers_with_damage : 1;
|
||||||
guint has_egl_surfaceless_context : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkX11DisplayClass
|
struct _GdkX11DisplayClass
|
||||||
@@ -176,8 +174,6 @@ struct _GdkX11DisplayClass
|
|||||||
const XEvent *event);
|
const XEvent *event);
|
||||||
};
|
};
|
||||||
|
|
||||||
GdkX11Screen * _gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
|
|
||||||
Window xrootwin);
|
|
||||||
void _gdk_x11_display_error_event (GdkDisplay *display,
|
void _gdk_x11_display_error_event (GdkDisplay *display,
|
||||||
XErrorEvent *error);
|
XErrorEvent *error);
|
||||||
gsize gdk_x11_display_get_max_request_size (GdkDisplay *display);
|
gsize gdk_x11_display_get_max_request_size (GdkDisplay *display);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user