Compare commits
498 Commits
gl-sync-wo
...
fix-5685
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4625b3c8a2 | ||
|
|
c237957ef0 | ||
|
|
d04690d05c | ||
|
|
f8bfb5fec2 | ||
|
|
2a78734aef | ||
|
|
ee6aae93d5 | ||
|
|
fb2a17a972 | ||
|
|
1c64438b12 | ||
|
|
634bea777f | ||
|
|
a2076dd537 | ||
|
|
75f9379cd5 | ||
|
|
f9b2d3104a | ||
|
|
679657cc0f | ||
|
|
d712bdcd6d | ||
|
|
aa0cd3a553 | ||
|
|
244d36d3f4 | ||
|
|
a19cf02b16 | ||
|
|
56b904f1e6 | ||
|
|
dd1e76e601 | ||
|
|
e850dc81ba | ||
|
|
942c8eec73 | ||
|
|
e7bb7785fa | ||
|
|
9705ccbe2f | ||
|
|
ace2122d45 | ||
|
|
80730a4014 | ||
|
|
0a3eceb15d | ||
|
|
f211a2177f | ||
|
|
c463685286 | ||
|
|
bf55685000 | ||
|
|
9048e391b6 | ||
|
|
f4be5c80c6 | ||
|
|
e8ea1b3c8b | ||
|
|
17c877659c | ||
|
|
b5345b7f25 | ||
|
|
b59d45c5c7 | ||
|
|
0fb5331c31 | ||
|
|
9a7bf66ed4 | ||
|
|
628157e44e | ||
|
|
3f5e1589e2 | ||
|
|
be8a77171d | ||
|
|
d31ba5f551 | ||
|
|
fb6e432afb | ||
|
|
ee7c0ed1e8 | ||
|
|
376f1053ec | ||
|
|
8aa095c4d7 | ||
|
|
f96d041246 | ||
|
|
2dc17aeca9 | ||
|
|
fda2010a9e | ||
|
|
ac799542ee | ||
|
|
060ab606a2 | ||
|
|
a1c02161ba | ||
|
|
3877a2e533 | ||
|
|
158facc2ca | ||
|
|
88dd6e630e | ||
|
|
8d839c96d9 | ||
|
|
31ec095ec7 | ||
|
|
b14a134a46 | ||
|
|
f3b0aa27ea | ||
|
|
fe2b6dd246 | ||
|
|
565c9aed94 | ||
|
|
9a4decc30f | ||
|
|
036f5816ac | ||
|
|
65b6150e78 | ||
|
|
664e3b737a | ||
|
|
428a2707b5 | ||
|
|
fbc8bfb303 | ||
|
|
a0382ef495 | ||
|
|
ef3c515cf1 | ||
|
|
707c63c6f9 | ||
|
|
18f91df7d8 | ||
|
|
cf332e2efa | ||
|
|
3addbe23f3 | ||
|
|
771b7d6caa | ||
|
|
de3c1d0c73 | ||
|
|
bb88f69b20 | ||
|
|
d72a6167ed | ||
|
|
fc83d263ab | ||
|
|
54e36f6b73 | ||
|
|
8d96b12cc7 | ||
|
|
d1256648f4 | ||
|
|
2322fecf3b | ||
|
|
2e2c41cef6 | ||
|
|
895d427c6a | ||
|
|
c2965aed35 | ||
|
|
11d9bbfd6e | ||
|
|
f63fc91b0e | ||
|
|
e041646bfc | ||
|
|
c3dde05d33 | ||
|
|
45434d501c | ||
|
|
b74d483f01 | ||
|
|
cd5af8c0d9 | ||
|
|
9a2cc79286 | ||
|
|
cc7d996a5c | ||
|
|
79e7078949 | ||
|
|
53cfbbbb65 | ||
|
|
bc592c92be | ||
|
|
6d380cdfb4 | ||
|
|
61d53b6402 | ||
|
|
fe79c7db16 | ||
|
|
bcb0882208 | ||
|
|
a36123c802 | ||
|
|
9f88dba162 | ||
|
|
98ff6c0d4d | ||
|
|
15d73a1adb | ||
|
|
6f93baf420 | ||
|
|
5cca7488d4 | ||
|
|
83d14bfa98 | ||
|
|
f0c076619d | ||
|
|
a05b73cb05 | ||
|
|
b4dc7f29d4 | ||
|
|
4f1ea18c10 | ||
|
|
7c60fb88b0 | ||
|
|
93edb08094 | ||
|
|
7a0e8f2b8b | ||
|
|
7ed8c5b6c7 | ||
|
|
d776ad789d | ||
|
|
86bbc13a61 | ||
|
|
664ce48a4c | ||
|
|
42f1b623bf | ||
|
|
6b7f0266ac | ||
|
|
ad84ee8352 | ||
|
|
c035384fc8 | ||
|
|
7b1644b2d0 | ||
|
|
aaac380053 | ||
|
|
dcc6cb8f1c | ||
|
|
0c1ec82a74 | ||
|
|
3eb9afb0ca | ||
|
|
36037a2ee8 | ||
|
|
23408f6dbf | ||
|
|
413abef01d | ||
|
|
4f8743a537 | ||
|
|
e24d4ba5db | ||
|
|
118361a085 | ||
|
|
7bdb146473 | ||
|
|
517b4d584c | ||
|
|
88d9244b98 | ||
|
|
fb4ae235a5 | ||
|
|
b7c5c04c65 | ||
|
|
bea38c1b4b | ||
|
|
d5a36a718f | ||
|
|
1c785f512f | ||
|
|
bc65b96e9c | ||
|
|
943851ab64 | ||
|
|
352b8cb70e | ||
|
|
dc50c790c5 | ||
|
|
6dd273c3f1 | ||
|
|
bc397b047e | ||
|
|
80f3fe4031 | ||
|
|
6f0976bace | ||
|
|
61ad0147bd | ||
|
|
582e74737c | ||
|
|
aafe8f4b38 | ||
|
|
2d695b6dcc | ||
|
|
3a423749e2 | ||
|
|
97d53b1e86 | ||
|
|
50d7727881 | ||
|
|
d564549f65 | ||
|
|
bf1a5d99cf | ||
|
|
7c96003471 | ||
|
|
fc74eed425 | ||
|
|
89d131de56 | ||
|
|
a35dc8dda6 | ||
|
|
0db9677b3a | ||
|
|
f00659d97f | ||
|
|
f2a0a8b8be | ||
|
|
0f02040292 | ||
|
|
4014e956cd | ||
|
|
6029c006b3 | ||
|
|
9ca2289547 | ||
|
|
72454a7113 | ||
|
|
e3dc282cc1 | ||
|
|
5f24218123 | ||
|
|
feebd68dd3 | ||
|
|
acf3f6beda | ||
|
|
5c9fb3a636 | ||
|
|
6a874e6887 | ||
|
|
4b73be18c7 | ||
|
|
670cf6201d | ||
|
|
196372f124 | ||
|
|
310662516b | ||
|
|
70b430edff | ||
|
|
c8a720aaa5 | ||
|
|
85d6f39ac7 | ||
|
|
a916e00dac | ||
|
|
913798b1d0 | ||
|
|
70fe37cf1b | ||
|
|
5583fa60c1 | ||
|
|
97e3c65251 | ||
|
|
334ca12d78 | ||
|
|
442fa8d972 | ||
|
|
12858114a2 | ||
|
|
4f6133e00a | ||
|
|
9ca3a52bf0 | ||
|
|
40d99839d6 | ||
|
|
111e8d2808 | ||
|
|
9b0b3029a6 | ||
|
|
f743b95161 | ||
|
|
bdd35c1695 | ||
|
|
2f273ba76a | ||
|
|
a2d14632de | ||
|
|
7a3e130efd | ||
|
|
c8d356a250 | ||
|
|
ffb7177c2e | ||
|
|
8b2202cd56 | ||
|
|
14a5c78d80 | ||
|
|
5fd2a6c8f3 | ||
|
|
6cb6f4a50f | ||
|
|
7b909fb310 | ||
|
|
d12bea03d2 | ||
|
|
deacc63d54 | ||
|
|
ead121a3c1 | ||
|
|
de4725dbd5 | ||
|
|
662f35562b | ||
|
|
9517d3d135 | ||
|
|
7f5504523f | ||
|
|
40b154bf28 | ||
|
|
f0e4293b83 | ||
|
|
87f820287a | ||
|
|
30586d75ac | ||
|
|
7a1573a381 | ||
|
|
bc42955a13 | ||
|
|
cdc008763b | ||
|
|
7fff188557 | ||
|
|
69238c1197 | ||
|
|
574380c744 | ||
|
|
d1fc1adae7 | ||
|
|
64697ea95b | ||
|
|
aaeec84d75 | ||
|
|
5822ba76d0 | ||
|
|
a6ad8ebe0c | ||
|
|
55faea1046 | ||
|
|
21ee81823e | ||
|
|
9efd8ef201 | ||
|
|
432e8664e1 | ||
|
|
6d2c5e51e0 | ||
|
|
b669295fd8 | ||
|
|
96e6332d28 | ||
|
|
59549d0665 | ||
|
|
3e3158ce12 | ||
|
|
cfc2de4e3d | ||
|
|
343852af7b | ||
|
|
51902bbce8 | ||
|
|
9b3fb66bd4 | ||
|
|
3ccf63b3c0 | ||
|
|
4655226907 | ||
|
|
4500fa633b | ||
|
|
be11202538 | ||
|
|
0fa1e71ef0 | ||
|
|
987b9cec3f | ||
|
|
a77beb39a1 | ||
|
|
ac8e053ab6 | ||
|
|
986275239f | ||
|
|
2ee1273244 | ||
|
|
248027a366 | ||
|
|
c823432eef | ||
|
|
98ac2de649 | ||
|
|
1cee54009a | ||
|
|
80b7c60150 | ||
|
|
e8c5a771e5 | ||
|
|
882dcda53b | ||
|
|
b488fae893 | ||
|
|
b962defc11 | ||
|
|
9ee0696923 | ||
|
|
f3c53ae69d | ||
|
|
8aea6fc1b5 | ||
|
|
d949afb80e | ||
|
|
08c583b1b3 | ||
|
|
1c663cb340 | ||
|
|
776910d03d | ||
|
|
c82b2d86c0 | ||
|
|
3ca4acdc1a | ||
|
|
c705dba2ee | ||
|
|
55ad241f43 | ||
|
|
d3efd80b90 | ||
|
|
a899c0af6e | ||
|
|
f8fb30b555 | ||
|
|
47aa0dcc7f | ||
|
|
32f0723bf0 | ||
|
|
90a3584c1d | ||
|
|
891b6dc4a9 | ||
|
|
c6ff7400a8 | ||
|
|
6620b7de92 | ||
|
|
d58071b4c1 | ||
|
|
f38df62e2b | ||
|
|
0581e38b09 | ||
|
|
74a00319dd | ||
|
|
611788fb53 | ||
|
|
500128d186 | ||
|
|
32cf104167 | ||
|
|
9b98426e71 | ||
|
|
9820d25cf9 | ||
|
|
8bbf220fdf | ||
|
|
3a0152b65f | ||
|
|
22ba6b1f33 | ||
|
|
718b5d5fe7 | ||
|
|
88dd64551c | ||
|
|
98eac8ac83 | ||
|
|
dbb2cb22ca | ||
|
|
71dbb5090e | ||
|
|
4b46097748 | ||
|
|
eb0f33d76b | ||
|
|
828f686fc9 | ||
|
|
681f8bed19 | ||
|
|
5fe32a46a0 | ||
|
|
e3548bb9ad | ||
|
|
61506648bf | ||
|
|
621b3b51ea | ||
|
|
784ba8bf12 | ||
|
|
d968659b43 | ||
|
|
48d3db8daa | ||
|
|
ca702b4596 | ||
|
|
5a5a36151a | ||
|
|
c91ba630a7 | ||
|
|
bc99ab38ce | ||
|
|
fe8c262351 | ||
|
|
1b000b5586 | ||
|
|
1b4f240883 | ||
|
|
496f68376b | ||
|
|
f019ff5287 | ||
|
|
c08e739996 | ||
|
|
8eb3c55709 | ||
|
|
40d4441fd8 | ||
|
|
471ebabd77 | ||
|
|
d8b7c909ea | ||
|
|
158165f769 | ||
|
|
2d90031dab | ||
|
|
2a862c05a1 | ||
|
|
93b6c7863b | ||
|
|
090f45a589 | ||
|
|
ca737b1411 | ||
|
|
b2af4006ba | ||
|
|
5d3942e5fa | ||
|
|
2bcc3cfb33 | ||
|
|
a7a498e803 | ||
|
|
75a417e337 | ||
|
|
dbaaa59758 | ||
|
|
73ba043b02 | ||
|
|
61e4eadbce | ||
|
|
0db2d0bc07 | ||
|
|
cd10e5dd1a | ||
|
|
c57d6c5575 | ||
|
|
73057b267e | ||
|
|
9d4bb77263 | ||
|
|
0d6cee9763 | ||
|
|
b33bfe26fe | ||
|
|
0cacaa08f5 | ||
|
|
cbf4a546b4 | ||
|
|
03732c1d48 | ||
|
|
568cf21486 | ||
|
|
f11d647aa4 | ||
|
|
49feaf465d | ||
|
|
9b0afd8bff | ||
|
|
495ca72232 | ||
|
|
e6f4464a3d | ||
|
|
cb0e4ee2be | ||
|
|
6f7b6ad61a | ||
|
|
1e599c9141 | ||
|
|
4cf42eb19c | ||
|
|
b0fc2f99ba | ||
|
|
2b4dd182c1 | ||
|
|
c141d0a70a | ||
|
|
6fa8033c7c | ||
|
|
de80f503e4 | ||
|
|
41b67c4722 | ||
|
|
1eae87621d | ||
|
|
5f502601c8 | ||
|
|
04d23c5cb9 | ||
|
|
d9b6f814ad | ||
|
|
871c46591a | ||
|
|
d906b456a8 | ||
|
|
32bc7ce987 | ||
|
|
cad5771a66 | ||
|
|
378f1421f0 | ||
|
|
a209a73c69 | ||
|
|
624458df9d | ||
|
|
fbfbaa484d | ||
|
|
3de10847b9 | ||
|
|
8be601da4f | ||
|
|
07b9a6fb75 | ||
|
|
5105d607de | ||
|
|
a9f03be588 | ||
|
|
d67bdb96ad | ||
|
|
c8f4535ed2 | ||
|
|
21cbf98942 | ||
|
|
300540f6b8 | ||
|
|
323ba14dde | ||
|
|
aaee1ee5bd | ||
|
|
70a711882c | ||
|
|
5717b95cad | ||
|
|
1b0f324be5 | ||
|
|
ca93512106 | ||
|
|
fbd4f06ee2 | ||
|
|
d553f6941d | ||
|
|
2173b7ccaa | ||
|
|
ca6642deed | ||
|
|
be6a4722c0 | ||
|
|
3b3b63062d | ||
|
|
7ec90abf24 | ||
|
|
ec49a912aa | ||
|
|
ae94417f80 | ||
|
|
24a6803958 | ||
|
|
4073371416 | ||
|
|
e5a391c0b9 | ||
|
|
6cb612ac15 | ||
|
|
9f64202a60 | ||
|
|
19c362f638 | ||
|
|
e51fa8b65b | ||
|
|
06d3bbafaf | ||
|
|
da8a1f4683 | ||
|
|
ad7d9bc409 | ||
|
|
94cde8d702 | ||
|
|
ec7b1f7208 | ||
|
|
864fbf89cd | ||
|
|
b8e928d703 | ||
|
|
0b4d41698b | ||
|
|
a9eca60b84 | ||
|
|
53c3f497f1 | ||
|
|
3183a21347 | ||
|
|
07f090f947 | ||
|
|
ad111087cc | ||
|
|
5092581be8 | ||
|
|
b261f7f533 | ||
|
|
779f9e5071 | ||
|
|
b07d9d1912 | ||
|
|
7b4692bcb0 | ||
|
|
f0a2b6f165 | ||
|
|
2dc6efd9ce | ||
|
|
1f4adb60bb | ||
|
|
f507dd4962 | ||
|
|
1bdb368e8b | ||
|
|
aec4bfcf3b | ||
|
|
7e18c2849b | ||
|
|
351abadee7 | ||
|
|
951db28f71 | ||
|
|
40e7a265a7 | ||
|
|
9a539cec57 | ||
|
|
724cf6bd70 | ||
|
|
5e4b43dcce | ||
|
|
fa43282695 | ||
|
|
662c251cd0 | ||
|
|
0d97d03fc1 | ||
|
|
cb0aaf0b2c | ||
|
|
0eb791eaaa | ||
|
|
073c836f96 | ||
|
|
0a0a03d913 | ||
|
|
d43724f5fc | ||
|
|
abf3cdb187 | ||
|
|
cca5de3c7f | ||
|
|
774696011d | ||
|
|
c9f54ca371 | ||
|
|
ce0123ea58 | ||
|
|
b30af72125 | ||
|
|
eb45b8083a | ||
|
|
f05d801e28 | ||
|
|
4afec951c7 | ||
|
|
51ed1442a2 | ||
|
|
01ff6c1c22 | ||
|
|
73f3ea9511 | ||
|
|
f1311dc053 | ||
|
|
a252aadadf | ||
|
|
300670dad4 | ||
|
|
44c95d3c96 | ||
|
|
d566771262 | ||
|
|
5f72b51105 | ||
|
|
e0afd22c84 | ||
|
|
869ab1cd1b | ||
|
|
730593fab5 | ||
|
|
d0798c9526 | ||
|
|
e6dfb8732a | ||
|
|
453ef8c7e1 | ||
|
|
819595d1a9 | ||
|
|
306276b689 | ||
|
|
bb15a7ef46 | ||
|
|
cd0fe13dae | ||
|
|
3dcea74e85 | ||
|
|
537c2f6c7a | ||
|
|
72379f64e9 | ||
|
|
4532c3020b | ||
|
|
b60bd8a73d | ||
|
|
37f12e4bf9 | ||
|
|
8967b2da01 | ||
|
|
dfb019509d | ||
|
|
a770b429ec | ||
|
|
7430bd7780 | ||
|
|
272a40a01a | ||
|
|
f121f607ae | ||
|
|
ff45145eac | ||
|
|
83c5f5ff0f | ||
|
|
87d21dc5c9 | ||
|
|
cef7e6b741 | ||
|
|
84b5e94ffd | ||
|
|
d2755e0385 | ||
|
|
2504215459 | ||
|
|
d45db3a961 | ||
|
|
b34c139028 | ||
|
|
6e6f2f652c | ||
|
|
3aac70f245 | ||
|
|
0cb3555a65 |
136
.gitlab-ci.yml
136
.gitlab-ci.yml
@@ -26,25 +26,31 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v40"
|
||||
FLATPAK_IMAGE: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v42"
|
||||
|
||||
.only-default:
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- tags
|
||||
workflow:
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
|
||||
default:
|
||||
retry:
|
||||
max: 2
|
||||
when:
|
||||
- 'runner_system_failure'
|
||||
- 'stuck_or_timeout_failure'
|
||||
- 'scheduler_failure'
|
||||
- 'api_failure'
|
||||
interruptible: true
|
||||
|
||||
style-check-diff:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
stage: check
|
||||
allow_failure: true
|
||||
when: manual
|
||||
script:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
|
||||
.build-fedora-default:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -54,6 +60,10 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/report-x11_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gles_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture_unstable.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-broadway_unstable.xml"
|
||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||
@@ -98,7 +108,8 @@ fedora-x86_64:
|
||||
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build waylandgles
|
||||
- .gitlab-ci/run-tests.sh _build wayland_gles
|
||||
- .gitlab-ci/run-tests.sh _build wayland_smalltexture
|
||||
- .gitlab-ci/run-tests.sh _build broadway
|
||||
|
||||
release-build:
|
||||
@@ -160,7 +171,6 @@ fedora-mingw64:
|
||||
- ninja -C _build
|
||||
|
||||
.mingw-defaults:
|
||||
extends: .only-default
|
||||
stage: build
|
||||
tags:
|
||||
- win32-ps
|
||||
@@ -192,9 +202,8 @@ msys2-mingw64:
|
||||
macos:
|
||||
# Sadly, this fails regularly, and its failure is never enlightening
|
||||
allow_failure: true
|
||||
extends: .only-default
|
||||
only:
|
||||
- branches@GNOME/gtk
|
||||
rules:
|
||||
- if: $CI_PROJECT_NAMESPACE == "GNOME"
|
||||
stage: build
|
||||
tags:
|
||||
- macos
|
||||
@@ -227,10 +236,9 @@ macos:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
|
||||
vs2017-x64:
|
||||
extends: .only-default
|
||||
# TODO: Uncomment this when ready to merge.
|
||||
#only:
|
||||
# - branches@GNOME/gtk
|
||||
# rules:
|
||||
# - if: $CI_PROJECT_NAMESPACE == "GNOME"
|
||||
stage: build
|
||||
tags:
|
||||
- win32-ps
|
||||
@@ -243,7 +251,7 @@ vs2017-x64:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
|
||||
.flatpak-defaults:
|
||||
image: $FLATPAK_IMAGE
|
||||
image: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
|
||||
stage: flatpak
|
||||
allow_failure: true
|
||||
tags:
|
||||
@@ -253,65 +261,67 @@ vs2017-x64:
|
||||
- "${APPID}-dev.flatpak"
|
||||
- 'repo.tar'
|
||||
expire_in: 1 day
|
||||
rules:
|
||||
# Only build Flatpak bundles automatically on main
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
- if: $CI_COMMIT_BRANCH != "main"
|
||||
when: "manual"
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
||||
|
||||
# Manual jobs, for branches and MRs
|
||||
.flatpak-manual:
|
||||
extends: .flatpak-defaults
|
||||
when: manual
|
||||
|
||||
# Only build Flatpak bundles automatically on main
|
||||
.flatpak-main:
|
||||
extends: .flatpak-defaults
|
||||
only:
|
||||
- main
|
||||
|
||||
flatpak-manual:demo:
|
||||
extends: .flatpak-manual
|
||||
flatpak:demo:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
|
||||
flatpak-main:demo:
|
||||
extends: .flatpak-main
|
||||
flatpak:demo:aarch64:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
tags:
|
||||
- flatpak-aarch64
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
|
||||
flatpak-manual:widget-factory:
|
||||
extends: .flatpak-manual
|
||||
flatpak:widget-factory:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
|
||||
flatpak-main:widget-factory:
|
||||
extends: .flatpak-main
|
||||
flatpak:widget-factory:aarch64:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
tags:
|
||||
- flatpak-aarch64
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
|
||||
flatpak-manual:icon-browser:
|
||||
extends: .flatpak-manual
|
||||
flatpak:icon-browser:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
|
||||
flatpak-main:icon-browser:
|
||||
extends: .flatpak-main
|
||||
flatpak:icon-browser:aarch64:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
tags:
|
||||
- flatpak-aarch64
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
|
||||
flatpak-manual:node-editor:
|
||||
extends: .flatpak-manual
|
||||
flatpak:node-editor:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
variables:
|
||||
APPID: org.gtk.gtk4.NodeEditor
|
||||
|
||||
flatpak-main:node-editor:
|
||||
extends: .flatpak-main
|
||||
flatpak:node-editor:aarch64:
|
||||
extends: '.flatpak-defaults'
|
||||
needs: []
|
||||
tags:
|
||||
- flatpak-aarch64
|
||||
variables:
|
||||
APPID: org.gtk.gtk4.NodeEditor
|
||||
|
||||
@@ -320,23 +330,35 @@ flatpak-main:node-editor:
|
||||
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
|
||||
nightly demo:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-main:demo']
|
||||
needs: ['flatpak-main:demo']
|
||||
needs: ['flatpak:demo']
|
||||
|
||||
nightly demo aarch64:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:demo:aarch64']
|
||||
|
||||
nightly factory:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-main:widget-factory']
|
||||
needs: ['flatpak-main:widget-factory']
|
||||
needs: ['flatpak:widget-factory']
|
||||
|
||||
nightly factory aarch64:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:widget-factory:aarch64']
|
||||
|
||||
nightly icon-browser:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-main:icon-browser']
|
||||
needs: ['flatpak-main:icon-browser']
|
||||
needs: ['flatpak:icon-browser']
|
||||
|
||||
nightly icon-browser aarch64:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:icon-browser:aarch64']
|
||||
|
||||
nightly node-editor:
|
||||
extends: '.publish_nightly'
|
||||
dependencies: ['flatpak-main:node-editor']
|
||||
needs: ['flatpak-main:node-editor']
|
||||
needs: ['flatpak:node-editor']
|
||||
|
||||
nightly node-editor aarch64:
|
||||
extends: '.publish_nightly'
|
||||
needs: ['flatpak:node-editor:aarch64']
|
||||
|
||||
static-scan:
|
||||
image: $FEDORA_IMAGE
|
||||
@@ -419,9 +441,9 @@ reference:
|
||||
publish-docs:
|
||||
image: fedora:latest
|
||||
stage: publish
|
||||
interruptible: false
|
||||
needs: ['reference']
|
||||
script:
|
||||
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
|
||||
only:
|
||||
refs:
|
||||
- main
|
||||
rules:
|
||||
- if: $CI_COMMIT_REF_NAME == "main"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:37
|
||||
FROM fedora:38
|
||||
|
||||
RUN dnf -y install \
|
||||
adwaita-icon-theme \
|
||||
@@ -82,6 +82,7 @@ RUN dnf -y install \
|
||||
python3-gobject \
|
||||
python3-jinja2 \
|
||||
python3-markdown \
|
||||
python3-packaging \
|
||||
python3-pip \
|
||||
python3-pygments \
|
||||
python3-typogrify \
|
||||
|
||||
@@ -20,6 +20,7 @@ flatpak build ${builddir} meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbuild-tests=false \
|
||||
-Dbuild-testsuite=false \
|
||||
-Dbuild-examples=false \
|
||||
-Dintrospection=disabled \
|
||||
-Ddemos=true \
|
||||
|
||||
@@ -23,6 +23,7 @@ push=0
|
||||
list=0
|
||||
print_help=0
|
||||
no_login=0
|
||||
no_cache=0
|
||||
|
||||
while (($# > 0)); do
|
||||
case "${1%%=*}" in
|
||||
@@ -34,6 +35,7 @@ while (($# > 0)); do
|
||||
--base|-b) read_arg base "$@" || shift;;
|
||||
--version|-v) read_arg base_version "$@" || shift;;
|
||||
--no-login) no_login=1;;
|
||||
--no-cache) no_cache=1;;
|
||||
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
|
||||
esac
|
||||
shift
|
||||
@@ -103,11 +105,21 @@ TAG="${REGISTRY}/gnome/gtk/${base}:${base_version}"
|
||||
|
||||
if [ $build == 1 ]; then
|
||||
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
|
||||
${CMD} build \
|
||||
${format} \
|
||||
--build-arg HOST_USER_ID="$UID" \
|
||||
--tag "${TAG}" \
|
||||
--file "${base}.Dockerfile" .
|
||||
if [ $no_cache == 0 ]; then
|
||||
${CMD} build \
|
||||
${format} \
|
||||
--build-arg HOST_USER_ID="$UID" \
|
||||
--tag "${TAG}" \
|
||||
--file "${base}.Dockerfile" .
|
||||
else
|
||||
${CMD} build \
|
||||
${format} \
|
||||
--no-cache \
|
||||
--build-arg HOST_USER_ID="$UID" \
|
||||
--tag "${TAG}" \
|
||||
--file "${base}.Dockerfile" .
|
||||
fi
|
||||
|
||||
exit $?
|
||||
fi
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ case "${backend}" in
|
||||
--suite=failing || true
|
||||
;;
|
||||
|
||||
wayland)
|
||||
wayland*)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
|
||||
@@ -63,33 +63,6 @@ case "${backend}" in
|
||||
kill ${compositor}
|
||||
;;
|
||||
|
||||
waylandgles)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
weston --backend=headless-backend.so --socket=wayland-6 --idle-time=0 &
|
||||
compositor=$!
|
||||
export WAYLAND_DISPLAY=wayland-6
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--no-suite=failing \
|
||||
--no-suite=flaky \
|
||||
--no-suite=gsk-compare-broadway
|
||||
exit_code=$?
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend}_unstable \
|
||||
--suite=flaky \
|
||||
--suite=failing || true
|
||||
|
||||
kill ${compositor}
|
||||
;;
|
||||
|
||||
broadway)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
|
||||
122
NEWS
122
NEWS
@@ -1,8 +1,118 @@
|
||||
Overview of Changes in 4.9.4, xx-xx-xxxx
|
||||
Overview of Changes in 4.11.1, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
Overview of Changes in 4.10.1, 14-03-2023
|
||||
=========================================
|
||||
|
||||
* GtkFileChooser
|
||||
- Improve search performance
|
||||
- Be safe against pathless files
|
||||
- Fix memory leaks
|
||||
- Only show local files in recent files
|
||||
- Show most recent files first
|
||||
- Make files non-selectable in selet_folder mode
|
||||
|
||||
* GtkListView / GtkColumnView / GtkGridView
|
||||
- Fix scrolling problems
|
||||
- Support CSS border-spacing
|
||||
|
||||
* GtkComboBox
|
||||
- Fix a size allocation problem
|
||||
|
||||
* gtk
|
||||
- Size allocation fixes
|
||||
|
||||
* Accessibility
|
||||
- Miscellaneous property fixes and improvements
|
||||
|
||||
* Wayland
|
||||
- Fix an ordering problem in surface disposal
|
||||
|
||||
* Windows
|
||||
- Fix Visual Studio build with older GLib
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Bulgarian
|
||||
Catalan
|
||||
Czech
|
||||
Danish
|
||||
Finnish
|
||||
Friulian
|
||||
Galician
|
||||
Georgian
|
||||
Hungarian
|
||||
Lithuanian
|
||||
Polish
|
||||
Portuguese
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.10.0, 04-03-2023
|
||||
=========================================
|
||||
|
||||
* GtkTextView
|
||||
- Document hanging indentation
|
||||
|
||||
* GtkListView
|
||||
- Fix a size allocation problem
|
||||
|
||||
* GtkFileChooser
|
||||
- Fix paned behavior
|
||||
- Fix a crash
|
||||
|
||||
* GtkText
|
||||
- Fix various problems with undo
|
||||
|
||||
* Accessibility
|
||||
- Make some getters transfer-full
|
||||
- Allow setting accessible parents and siblings
|
||||
- Add a role for toggle buttons
|
||||
- Miscellaneous property fixes and improvements
|
||||
|
||||
* gtk
|
||||
- Improve the handling resize-during-size-allocate
|
||||
|
||||
* gdk
|
||||
- Introduce GdkTextureDownloader and use it
|
||||
- Make gdk_texture_get_format public
|
||||
|
||||
* gsk
|
||||
- Make mask nodes more versatile
|
||||
- Improve the GL implementation for texture scale nodes
|
||||
|
||||
* X11
|
||||
- Fix key handling during DND
|
||||
|
||||
* Tools
|
||||
- gtk-builder-tool: Try harder to handle templates
|
||||
- gtk-builder-tool: Prefer properties over <child>
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Belarusian
|
||||
Bulgarian
|
||||
Indonesian
|
||||
Galician
|
||||
Georgian
|
||||
German
|
||||
Hebrew
|
||||
Lithuanian
|
||||
Portuguese
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.9.4, 12-02-2023
|
||||
========================================
|
||||
|
||||
* Printing:
|
||||
- Add a CPDB print backend
|
||||
- Add a CPDB backend
|
||||
- Drop the lpr backend
|
||||
|
||||
* GtkFileDialog:
|
||||
- Robustness fixes
|
||||
@@ -10,20 +120,28 @@ Overview of Changes in 4.9.4, xx-xx-xxxx
|
||||
* GtkScaleButton:
|
||||
- Add an 'active' property
|
||||
|
||||
* GtkSearchEntry:
|
||||
- Add placeholder text
|
||||
|
||||
* Fix conflicting type names between gtk and gio
|
||||
|
||||
* Gsk:
|
||||
- Settable filtering for scaled textures
|
||||
- Add mask nodes
|
||||
- Some robustness and crash fixes
|
||||
|
||||
* Wayland:
|
||||
- Handle dispatch failing in more places
|
||||
|
||||
* Deprecations:
|
||||
- GtkVolumeButton
|
||||
|
||||
* Translation updates:
|
||||
Belarusian
|
||||
Chinese (Taiwan)
|
||||
Georgian
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.9.3, 04-02-2023
|
||||
|
||||
@@ -9,7 +9,7 @@ constraint_editor_sources = [
|
||||
|
||||
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||
'constraint-editor.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-constraint-editor',
|
||||
|
||||
@@ -5,7 +5,8 @@ enum
|
||||
{
|
||||
PROP_TEXTURE = 1,
|
||||
PROP_FILTER,
|
||||
PROP_SCALE
|
||||
PROP_SCALE,
|
||||
PROP_ANGLE,
|
||||
};
|
||||
|
||||
struct _Demo3Widget
|
||||
@@ -14,6 +15,7 @@ struct _Demo3Widget
|
||||
|
||||
GdkTexture *texture;
|
||||
float scale;
|
||||
float angle;
|
||||
GskScalingFilter filter;
|
||||
|
||||
GtkWidget *menu;
|
||||
@@ -26,10 +28,85 @@ struct _Demo3WidgetClass
|
||||
|
||||
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static gboolean
|
||||
query_tooltip (GtkWidget *widget,
|
||||
int x,
|
||||
int y,
|
||||
gboolean keyboard_mode,
|
||||
GtkTooltip *tooltip,
|
||||
gpointer data)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
GtkWidget *grid;
|
||||
GtkWidget *label;
|
||||
char *s, *s2;
|
||||
const char *filter[] = { "Linear", "Nearest", "Trilinear" };
|
||||
int precision, l;
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
||||
label = gtk_label_new ("Texture");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
s = g_strdup_printf ("%d\342\200\206\303\227\342\200\206%d",
|
||||
gdk_texture_get_width (self->texture),
|
||||
gdk_texture_get_height (self->texture));
|
||||
label = gtk_label_new (s);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Rotation");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
||||
s = g_strdup_printf ("%.1f", self->angle);
|
||||
if (g_str_has_suffix (s, ".0"))
|
||||
s[strlen (s) - 2] = '\0';
|
||||
s2 = g_strconcat (s, "\302\260", NULL);
|
||||
label = gtk_label_new (s2);
|
||||
g_free (s2);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Scale");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
||||
|
||||
precision = 1;
|
||||
do {
|
||||
s = g_strdup_printf ("%.*f", precision, self->scale);
|
||||
l = strlen (s) - 1;
|
||||
while (s[l] == '0')
|
||||
l--;
|
||||
if (s[l] == '.')
|
||||
s[l] = '\0';
|
||||
precision++;
|
||||
} while (strcmp (s, "0") == 0);
|
||||
|
||||
label = gtk_label_new (s);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Filter");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
|
||||
label = gtk_label_new (filter[self->filter]);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
|
||||
|
||||
gtk_tooltip_set_custom (tooltip, grid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
demo3_widget_init (Demo3Widget *self)
|
||||
{
|
||||
self->scale = 1.f;
|
||||
self->angle = 0.f;
|
||||
self->filter = GSK_SCALING_FILTER_LINEAR;
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
@@ -52,26 +129,35 @@ demo3_widget_snapshot (GtkWidget *widget,
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int x, y, width, height;
|
||||
double w, h;
|
||||
GskRenderNode *node;
|
||||
double w, h, w2, h2;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
w = self->scale * gdk_texture_get_width (self->texture);
|
||||
h = self->scale * gdk_texture_get_height (self->texture);
|
||||
w2 = w = self->scale * gdk_texture_get_width (self->texture);
|
||||
h2 = h = self->scale * gdk_texture_get_height (self->texture);
|
||||
|
||||
x = MAX (0, (width - ceil (w)) / 2);
|
||||
y = MAX (0, (height - ceil (h)) / 2);
|
||||
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
|
||||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
|
||||
{
|
||||
double s = w2;
|
||||
w2 = h2;
|
||||
h2 = s;
|
||||
}
|
||||
|
||||
x = (width - ceil (w2)) / 2;
|
||||
y = (height - ceil (h2)) / 2;
|
||||
|
||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
|
||||
node = gsk_texture_scale_node_new (self->texture,
|
||||
&GRAPHENE_RECT_INIT (0, 0, w, h),
|
||||
self->filter);
|
||||
gtk_snapshot_append_node (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (w2 / 2, h2 / 2));
|
||||
gtk_snapshot_rotate (snapshot, self->angle);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- w / 2, - h / 2));
|
||||
gtk_snapshot_append_scaled_texture (snapshot,
|
||||
self->texture,
|
||||
self->filter,
|
||||
&GRAPHENE_RECT_INIT (0, 0, w, h));
|
||||
gtk_snapshot_restore (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
@@ -86,14 +172,26 @@ demo3_widget_measure (GtkWidget *widget,
|
||||
int *natural_baseline)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int width, height;
|
||||
int size;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = gdk_texture_get_width (self->texture);
|
||||
else
|
||||
size = gdk_texture_get_height (self->texture);
|
||||
width = gdk_texture_get_width (self->texture);
|
||||
height = gdk_texture_get_height (self->texture);
|
||||
|
||||
*minimum = *natural = self->scale * size;
|
||||
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
|
||||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
|
||||
{
|
||||
int s = width;
|
||||
width = height;
|
||||
height = s;
|
||||
}
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = width;
|
||||
else
|
||||
size = height;
|
||||
|
||||
*minimum = *natural = (int) ceil (self->scale * size);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -111,6 +209,8 @@ demo3_widget_size_allocate (GtkWidget *widget,
|
||||
gtk_popover_present (GTK_POPOVER (self->menu));
|
||||
}
|
||||
|
||||
static void update_actions (Demo3Widget *self);
|
||||
|
||||
static void
|
||||
demo3_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -124,11 +224,24 @@ demo3_widget_set_property (GObject *object,
|
||||
case PROP_TEXTURE:
|
||||
g_clear_object (&self->texture);
|
||||
self->texture = g_value_dup_object (value);
|
||||
self->scale = 1.f;
|
||||
self->angle = 0.f;
|
||||
self->filter = GSK_SCALING_FILTER_LINEAR;
|
||||
update_actions (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
g_object_notify (object, "scale");
|
||||
g_object_notify (object, "angle");
|
||||
g_object_notify (object, "filter");
|
||||
break;
|
||||
|
||||
case PROP_SCALE:
|
||||
self->scale = g_value_get_float (value);
|
||||
update_actions (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
case PROP_ANGLE:
|
||||
self->angle = fmodf (g_value_get_float (value), 360.f);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
@@ -161,6 +274,10 @@ demo3_widget_get_property (GObject *object,
|
||||
g_value_set_float (value, self->scale);
|
||||
break;
|
||||
|
||||
case PROP_ANGLE:
|
||||
g_value_set_float (value, self->angle);
|
||||
break;
|
||||
|
||||
case PROP_FILTER:
|
||||
g_value_set_enum (value, self->filter);
|
||||
break;
|
||||
@@ -186,6 +303,14 @@ pressed_cb (GtkGestureClick *gesture,
|
||||
gtk_popover_popup (GTK_POPOVER (self->menu));
|
||||
}
|
||||
|
||||
static void
|
||||
update_actions (Demo3Widget *self)
|
||||
{
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.in", self->scale < 1024.);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.out", self->scale > 1./1024.);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.reset", self->scale != 1.);
|
||||
}
|
||||
|
||||
static void
|
||||
zoom_cb (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
@@ -195,19 +320,30 @@ zoom_cb (GtkWidget *widget,
|
||||
float scale;
|
||||
|
||||
if (g_str_equal (action_name, "zoom.in"))
|
||||
scale = MIN (10, self->scale * M_SQRT2);
|
||||
scale = MIN (1024., self->scale * M_SQRT2);
|
||||
else if (g_str_equal (action_name, "zoom.out"))
|
||||
scale = MAX (0.01, self->scale / M_SQRT2);
|
||||
else
|
||||
scale = MAX (1./1024., self->scale / M_SQRT2);
|
||||
else if (g_str_equal (action_name, "zoom.reset"))
|
||||
scale = 1.0;
|
||||
|
||||
gtk_widget_action_set_enabled (widget, "zoom.in", scale < 10);
|
||||
gtk_widget_action_set_enabled (widget, "zoom.out", scale > 0.01);
|
||||
gtk_widget_action_set_enabled (widget, "zoom.reset", scale != 1);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
g_object_set (widget, "scale", scale, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
rotate_cb (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int angle;
|
||||
|
||||
g_variant_get (parameter, "i", &angle);
|
||||
|
||||
g_object_set (widget, "angle", fmodf (self->angle + angle, 360.f), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
{
|
||||
@@ -229,7 +365,12 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SCALE,
|
||||
g_param_spec_float ("scale", NULL, NULL,
|
||||
0.0, 10.0, 1.0,
|
||||
1./1024., 1024., 1.0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ANGLE,
|
||||
g_param_spec_float ("angle", NULL, NULL,
|
||||
0.0, 360.0, 0.0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_FILTER,
|
||||
@@ -241,6 +382,7 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "zoom.reset", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "rotate", "i", rotate_cb);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
|
||||
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu);
|
||||
@@ -255,7 +397,12 @@ demo3_widget_new (const char *resource)
|
||||
|
||||
texture = gdk_texture_new_from_resource (resource);
|
||||
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET,
|
||||
"texture", texture,
|
||||
"has-tooltip", TRUE,
|
||||
NULL);
|
||||
|
||||
g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip), NULL);
|
||||
|
||||
g_object_unref (texture);
|
||||
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
<attribute name="label">1∶1</attribute>
|
||||
<attribute name="action">zoom.reset</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">Rotate</attribute>
|
||||
<attribute name="action">rotate</attribute>
|
||||
<attribute name="target" type="i">90</attribute>
|
||||
</item>
|
||||
</menu>
|
||||
<template class="Demo3Widget">
|
||||
<child>
|
||||
|
||||
@@ -2,12 +2,19 @@
|
||||
#include "demo4widget.h"
|
||||
#include "hsla.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PROGRESS,
|
||||
};
|
||||
|
||||
struct _Demo4Widget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
PangoLayout *layout;
|
||||
GskColorStop stops[8];
|
||||
gsize n_stops;
|
||||
double progress;
|
||||
|
||||
guint tick;
|
||||
};
|
||||
@@ -49,6 +56,8 @@ demo4_widget_init (Demo4Widget *self)
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
|
||||
self->progress = 0.5;
|
||||
|
||||
self->n_stops = 8;
|
||||
self->stops[0].offset = 0;
|
||||
self->stops[0].color = (GdkRGBA) { 1, 0, 0, 1 };
|
||||
@@ -83,16 +92,24 @@ demo4_widget_dispose (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
demo4_widget_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
demo4_widget_snapshot_content (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot,
|
||||
GskMaskMode mode)
|
||||
{
|
||||
Demo4Widget *self = DEMO4_WIDGET (widget);
|
||||
int width, height;
|
||||
int width, height, layout_width, layout_height;
|
||||
double scale;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
gtk_snapshot_push_mask (snapshot);
|
||||
gtk_snapshot_push_mask (snapshot, mode);
|
||||
pango_layout_get_pixel_size (self->layout, &layout_width, &layout_height);
|
||||
scale = MIN ((double) width / layout_width, (double) height / layout_height);
|
||||
gtk_snapshot_translate (snapshot,
|
||||
&GRAPHENE_POINT_INIT ((width - scale * layout_width) / 2,
|
||||
(height - scale * layout_height) / 2));
|
||||
gtk_snapshot_scale (snapshot, scale, scale);
|
||||
gtk_snapshot_append_layout (snapshot, self->layout, &(GdkRGBA) { 0, 0, 0, 1 });
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
@@ -105,6 +122,84 @@ demo4_widget_snapshot (GtkWidget *widget,
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
demo4_widget_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
Demo4Widget *self = DEMO4_WIDGET (widget);
|
||||
int width, height;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_INVERTED_LUMINANCE);
|
||||
gtk_snapshot_append_linear_gradient (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
&GRAPHENE_POINT_INIT (0, 0),
|
||||
&GRAPHENE_POINT_INIT (width, 0),
|
||||
(GskColorStop[2]) {
|
||||
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
|
||||
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
|
||||
}, 2);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_INVERTED_ALPHA);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_LUMINANCE);
|
||||
gtk_snapshot_append_linear_gradient (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
&GRAPHENE_POINT_INIT (0, 0),
|
||||
&GRAPHENE_POINT_INIT (width, 0),
|
||||
(GskColorStop[2]) {
|
||||
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
|
||||
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
|
||||
}, 2);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_ALPHA);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
demo4_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
Demo4Widget *self = DEMO4_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PROGRESS:
|
||||
self->progress = g_value_get_double (value);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo4_widget_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
Demo4Widget *self = DEMO4_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PROGRESS:
|
||||
g_value_set_double (value, self->progress);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo4_widget_class_init (Demo4WidgetClass *class)
|
||||
{
|
||||
@@ -112,8 +207,15 @@ demo4_widget_class_init (Demo4WidgetClass *class)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = demo4_widget_dispose;
|
||||
object_class->get_property = demo4_widget_get_property;
|
||||
object_class->set_property = demo4_widget_set_property;
|
||||
|
||||
widget_class->snapshot = demo4_widget_snapshot;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PROGRESS,
|
||||
g_param_spec_double ("progress", NULL, NULL,
|
||||
0.0, 1.0, 0.5,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -121,3 +223,4 @@ demo4_widget_new (void)
|
||||
{
|
||||
return g_object_new (DEMO4_TYPE_WIDGET, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -356,6 +356,10 @@ canvas_item_start_editing (CanvasItem *item)
|
||||
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
double x, y;
|
||||
} Hotspot;
|
||||
|
||||
static GdkContentProvider *
|
||||
prepare (GtkDragSource *source,
|
||||
double x,
|
||||
@@ -363,6 +367,7 @@ prepare (GtkDragSource *source,
|
||||
{
|
||||
GtkWidget *canvas;
|
||||
GtkWidget *item;
|
||||
Hotspot *hotspot;
|
||||
|
||||
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
|
||||
@@ -373,6 +378,10 @@ prepare (GtkDragSource *source,
|
||||
|
||||
g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
|
||||
|
||||
hotspot = g_new (Hotspot, 1);
|
||||
gtk_widget_translate_coordinates (canvas, item, x, y, &hotspot->x, &hotspot->y);
|
||||
g_object_set_data_full (G_OBJECT (canvas), "hotspot", hotspot, g_free);
|
||||
|
||||
return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item);
|
||||
}
|
||||
|
||||
@@ -383,12 +392,14 @@ drag_begin (GtkDragSource *source,
|
||||
GtkWidget *canvas;
|
||||
CanvasItem *item;
|
||||
GdkPaintable *paintable;
|
||||
Hotspot *hotspot;
|
||||
|
||||
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
item = CANVAS_ITEM (g_object_get_data (G_OBJECT (canvas), "dragged-item"));
|
||||
hotspot = (Hotspot *) g_object_get_data (G_OBJECT (canvas), "hotspot");
|
||||
|
||||
paintable = canvas_item_get_drag_icon (item);
|
||||
gtk_drag_source_set_icon (source, paintable, item->r, item->r);
|
||||
gtk_drag_source_set_icon (source, paintable, hotspot->x, hotspot->y);
|
||||
g_object_unref (paintable);
|
||||
|
||||
gtk_widget_set_opacity (GTK_WIDGET (item), 0.3);
|
||||
|
||||
@@ -48,14 +48,16 @@
|
||||
#define VERTICES_PER_TOOTH 34
|
||||
#define GEAR_VERTEX_STRIDE 6
|
||||
|
||||
#ifndef HAVE_SINCOS
|
||||
static void
|
||||
sincos (double x, double *_sin, double *_cos)
|
||||
static inline void
|
||||
_sincos (double x, double *_sin, double *_cos)
|
||||
{
|
||||
#ifdef HAVE_SINCOS
|
||||
sincos (x, _sin, _cos);
|
||||
#else
|
||||
*_sin = sin (x);
|
||||
*_cos = cos (x);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Struct describing the vertices in triangle strip
|
||||
@@ -307,11 +309,11 @@ create_gear (GLfloat inner_radius,
|
||||
struct point p[7];
|
||||
|
||||
/* Calculate needed sin/cos for various angles */
|
||||
sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
|
||||
sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
|
||||
sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
|
||||
sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
|
||||
sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
|
||||
_sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
|
||||
_sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
|
||||
_sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
|
||||
_sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
|
||||
_sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
|
||||
|
||||
GEAR_POINT(p[0], r2, 1);
|
||||
GEAR_POINT(p[1], r2, 2);
|
||||
@@ -520,7 +522,7 @@ void perspective(GLfloat *m, GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloa
|
||||
identity(tmp);
|
||||
|
||||
deltaZ = zFar - zNear;
|
||||
sincos(radians, &sine, &cosine);
|
||||
_sincos(radians, &sine, &cosine);
|
||||
|
||||
if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
|
||||
return;
|
||||
|
||||
@@ -30,90 +30,86 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="show-separators">1</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
</style>
|
||||
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="switch_label">
|
||||
<property name="label" translatable="yes">Switch</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkLabel" id="switch_label">
|
||||
<property name="label" translatable="yes">Switch</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="check_label">
|
||||
<property name="label" translatable="yes">Check</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="check">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkLabel" id="check_label">
|
||||
<property name="label" translatable="yes">Check</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="check">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="image_label">
|
||||
<property name="label" translatable="yes">Click here!</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="opacity">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkLabel" id="image_label">
|
||||
<property name="label" translatable="yes">Click here!</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="opacity">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -134,146 +130,142 @@
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="show-separators">1</property>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
<class name="boxed-list"/>
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="scale_label">
|
||||
<property name="label" translatable="yes">Scale</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="draw-value">0</property>
|
||||
<property name="width-request">150</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="scale_label">
|
||||
<property name="label" translatable="yes">Scale</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="draw-value">0</property>
|
||||
<property name="width-request">150</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="spin_label">
|
||||
<property name="label" translatable="yes">Spinbutton</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="dropdown_label">
|
||||
<property name="label" translatable="yes">Dropdown</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Choice 1</item>
|
||||
<item>Choice 2</item>
|
||||
<item>Choice 3</item>
|
||||
<item>Choice 4</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="spin_label">
|
||||
<property name="label" translatable="yes">Spinbutton</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="dropdown_label">
|
||||
<property name="label" translatable="yes">Dropdown</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Choice 1</item>
|
||||
<item>Choice 2</item>
|
||||
<item>Choice 3</item>
|
||||
<item>Choice 4</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="entry_label">
|
||||
<property name="label" translatable="yes">Entry</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="placeholder-text">Type here…</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="entry_label">
|
||||
<property name="label" translatable="yes">Entry</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="placeholder-text">Type here…</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -18,7 +18,8 @@ do_mask (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *demo;
|
||||
GtkWidget *scale;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Mask Nodes");
|
||||
@@ -30,11 +31,17 @@ do_mask (GtkWidget *do_widget)
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
widget = demo4_widget_new ();
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_widget_set_vexpand (widget, TRUE);
|
||||
demo = demo4_widget_new ();
|
||||
gtk_widget_set_hexpand (demo, TRUE);
|
||||
gtk_widget_set_vexpand (demo, TRUE);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), widget);
|
||||
gtk_box_append (GTK_BOX (box), demo);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 1, 0.1);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 0.5);
|
||||
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value", demo, "progress", 0);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), scale);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,18 +1,120 @@
|
||||
/* Menu
|
||||
* #Keywords: action, zoom
|
||||
*
|
||||
* Demonstrates how to add a context menu to a custom widget
|
||||
* and connect it with widget actions.
|
||||
/* Image Scaling
|
||||
* #Keywords: zoom, scale, filter, action, menu
|
||||
*
|
||||
* The custom widget we create here is similar to a GtkPicture,
|
||||
* but allows setting a zoom level for the displayed paintable.
|
||||
* but allows setting a zoom level and filtering mode for the
|
||||
* displayed paintable.
|
||||
*
|
||||
* Our context menu has items to change the zoom level.
|
||||
* It also demonstrates how to add a context menu to a custom
|
||||
* widget and connect it with widget actions.
|
||||
*
|
||||
* The context menu has items to change the zoom level.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "demo3widget.h"
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
GdkTexture *texture;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
texture = gdk_texture_new_from_file (file, &error);
|
||||
g_object_unref (file);
|
||||
if (!texture)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set (G_OBJECT (data), "texture", texture, NULL);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
open_file (GtkWidget *picker,
|
||||
GtkWidget *demo)
|
||||
{
|
||||
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (picker));
|
||||
GtkFileDialog *dialog;
|
||||
GtkFileFilter *filter;
|
||||
GListStore *filters;
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_set_name (filter, "Images");
|
||||
gtk_file_filter_add_pixbuf_formats (filter);
|
||||
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
|
||||
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
|
||||
g_object_unref (filters);
|
||||
|
||||
gtk_file_dialog_open (dialog, parent, NULL, file_opened, demo);
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
rotate (GtkWidget *button,
|
||||
GtkWidget *demo)
|
||||
{
|
||||
float angle;
|
||||
|
||||
g_object_get (demo, "angle", &angle, NULL);
|
||||
|
||||
angle = fmodf (angle + 90.f, 360.f);
|
||||
|
||||
g_object_set (demo, "angle", angle, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transform_to (GBinding *binding,
|
||||
const GValue *src,
|
||||
GValue *dest,
|
||||
gpointer user_data)
|
||||
{
|
||||
double from;
|
||||
float to;
|
||||
|
||||
from = g_value_get_double (src);
|
||||
to = (float) pow (2., from);
|
||||
g_value_set_float (dest, to);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transform_from (GBinding *binding,
|
||||
const GValue *src,
|
||||
GValue *dest,
|
||||
gpointer user_data)
|
||||
{
|
||||
float to;
|
||||
double from;
|
||||
|
||||
to = g_value_get_float (src);
|
||||
from = log2 (to);
|
||||
g_value_set_double (dest, from);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_menu (GtkWidget *do_widget)
|
||||
@@ -27,9 +129,10 @@ do_menu (GtkWidget *do_widget)
|
||||
GtkWidget *widget;
|
||||
GtkWidget *scale;
|
||||
GtkWidget *dropdown;
|
||||
GtkWidget *button;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
@@ -48,19 +151,35 @@ do_menu (GtkWidget *do_widget)
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_box_append (GTK_BOX (box), box2);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Open File");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
|
||||
gtk_box_append (GTK_BOX (box2), button);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Rotate");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
|
||||
gtk_box_append (GTK_BOX (box2), button);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
|
||||
gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
|
||||
gtk_widget_set_tooltip_text (scale, "Zoom");
|
||||
gtk_range_set_value (GTK_RANGE (scale), 0.);
|
||||
gtk_widget_set_hexpand (scale, TRUE);
|
||||
gtk_box_append (GTK_BOX (box2), scale);
|
||||
|
||||
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
|
||||
gtk_widget_set_tooltip_text (dropdown, "Filter");
|
||||
gtk_box_append (GTK_BOX (box2), dropdown);
|
||||
|
||||
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
|
||||
|
||||
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
|
||||
g_object_bind_property_full (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL,
|
||||
transform_to,
|
||||
transform_from,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -225,7 +225,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
|
||||
else
|
||||
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
|
||||
'demo.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir()
|
||||
)
|
||||
endif
|
||||
|
||||
|
||||
@@ -13,20 +13,13 @@
|
||||
static GtkWidget *app_picker;
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
set_file (GFile *file,
|
||||
gpointer data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
char *name;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
|
||||
return;
|
||||
@@ -40,6 +33,25 @@ file_opened (GObject *source,
|
||||
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
set_file (file, data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abort_mission (gpointer data)
|
||||
{
|
||||
@@ -130,11 +142,28 @@ launch_uri (GtkButton *picker)
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_drop (GtkDropTarget *target,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
set_file (g_value_get_object (value), data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_pickers (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *table, *label, *picker, *button;
|
||||
GtkDropTarget *drop_target;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@@ -179,7 +208,13 @@ do_pickers (GtkWidget *do_widget)
|
||||
|
||||
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||
|
||||
label = gtk_label_new ("None");
|
||||
|
||||
drop_target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
|
||||
g_signal_connect (drop_target, "drop", G_CALLBACK (on_drop), label);
|
||||
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (drop_target));
|
||||
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
|
||||
@@ -22,6 +22,7 @@ show_shortcuts (GtkWidget *window,
|
||||
gtk_window_set_transient_for (GTK_WINDOW (overlay), GTK_WINDOW (window));
|
||||
g_object_set (overlay, "view-name", view, NULL);
|
||||
g_object_unref (builder);
|
||||
gtk_window_present (GTK_WINDOW (overlay));
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
|
||||
@@ -8,7 +8,7 @@ iconbrowser_sources = [
|
||||
|
||||
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
|
||||
'iconbrowser.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-icon-browser',
|
||||
|
||||
@@ -7,7 +7,7 @@ node_editor_sources = [
|
||||
|
||||
node_editor_resources = gnome.compile_resources('node_editor_resources',
|
||||
'node-editor.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-node-editor',
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
#include "gsk/vulkan/gskvulkanrenderer.h"
|
||||
#endif
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gsize start_chars;
|
||||
@@ -643,23 +648,34 @@ save_cb (GtkWidget *button,
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
create_texture (NodeEditorWindow *self)
|
||||
static GskRenderNode *
|
||||
create_node (NodeEditorWindow *self)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GtkSnapshot *snapshot;
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
|
||||
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
|
||||
if (paintable == NULL ||
|
||||
gdk_paintable_get_intrinsic_width (paintable) <= 0 ||
|
||||
gdk_paintable_get_intrinsic_height (paintable) <= 0)
|
||||
return NULL;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
create_texture (NodeEditorWindow *self)
|
||||
{
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *node;
|
||||
GdkTexture *texture;
|
||||
|
||||
node = create_node (self);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -670,6 +686,58 @@ create_texture (NodeEditorWindow *self)
|
||||
return texture;
|
||||
}
|
||||
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
static cairo_status_t
|
||||
cairo_serializer_write (gpointer user_data,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
g_byte_array_append (user_data, data, length);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
create_svg (GskRenderNode *node,
|
||||
GError **error)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
graphene_rect_t bounds;
|
||||
GByteArray *array;
|
||||
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
array = g_byte_array_new ();
|
||||
|
||||
surface = cairo_svg_surface_create_for_stream (cairo_serializer_write,
|
||||
array,
|
||||
bounds.size.width,
|
||||
bounds.size.height);
|
||||
cairo_svg_surface_set_document_unit (surface, CAIRO_SVG_UNIT_PX);
|
||||
cairo_surface_set_device_offset (surface, -bounds.origin.x, -bounds.origin.y);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
gsk_render_node_draw (node, cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_finish (surface);
|
||||
if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
cairo_surface_destroy (surface);
|
||||
return g_byte_array_free_to_bytes (array);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"%s", cairo_status_to_string (cairo_surface_status (surface)));
|
||||
cairo_surface_destroy (surface);
|
||||
g_byte_array_unref (array);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static GdkTexture *
|
||||
create_cairo_texture (NodeEditorWindow *self)
|
||||
{
|
||||
@@ -702,50 +770,140 @@ create_cairo_texture (NodeEditorWindow *self)
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_response_cb (GObject *source,
|
||||
export_image_saved_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_file_replace_contents_finish (G_FILE (source), result, NULL, &error))
|
||||
{
|
||||
GtkAlertDialog *alert;
|
||||
|
||||
alert = gtk_alert_dialog_new ("Exporting to image failed");
|
||||
gtk_alert_dialog_set_detail (alert, error->message);
|
||||
gtk_alert_dialog_show (alert, NULL);
|
||||
g_object_unref (alert);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_response_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *user_data)
|
||||
void *user_data)
|
||||
{
|
||||
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
|
||||
GdkTexture *texture = user_data;
|
||||
GskRenderNode *node = user_data;
|
||||
GFile *file;
|
||||
char *uri;
|
||||
GBytes *bytes;
|
||||
|
||||
file = gtk_file_dialog_save_finish (dialog, result, NULL);
|
||||
if (file)
|
||||
if (file == NULL)
|
||||
{
|
||||
if (!gdk_texture_save_to_png (texture, g_file_peek_path (file)))
|
||||
gsk_render_node_unref (node);
|
||||
return;
|
||||
}
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
if (g_str_has_suffix (uri, "svg"))
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
bytes = create_svg (node, &error);
|
||||
if (bytes == NULL)
|
||||
{
|
||||
GtkAlertDialog *alert;
|
||||
|
||||
alert = gtk_alert_dialog_new ("Exporting to image failed");
|
||||
gtk_alert_dialog_show (alert, GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))));
|
||||
gtk_alert_dialog_set_detail (alert, error->message);
|
||||
gtk_alert_dialog_show (alert, NULL);
|
||||
g_object_unref (alert);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GskRenderer *renderer;
|
||||
|
||||
g_object_unref (texture);
|
||||
renderer = gsk_gl_renderer_new ();
|
||||
if (!gsk_renderer_realize (renderer, NULL, NULL))
|
||||
{
|
||||
g_object_unref (renderer);
|
||||
renderer = gsk_cairo_renderer_new ();
|
||||
if (!gsk_renderer_realize (renderer, NULL, NULL))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
texture = gsk_renderer_render_texture (renderer, node, NULL);
|
||||
gsk_renderer_unrealize (renderer);
|
||||
g_object_unref (renderer);
|
||||
|
||||
if (g_str_has_suffix (uri, "tiff"))
|
||||
bytes = gdk_texture_save_to_tiff_bytes (texture);
|
||||
else
|
||||
bytes = gdk_texture_save_to_png_bytes (texture);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
g_free (uri);
|
||||
|
||||
if (bytes)
|
||||
{
|
||||
g_file_replace_contents_bytes_async (file,
|
||||
bytes,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
export_image_saved_cb,
|
||||
NULL);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
gsk_render_node_unref (node);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
static void
|
||||
export_image_cb (GtkWidget *button,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GskRenderNode *node;
|
||||
GtkFileDialog *dialog;
|
||||
GtkFileFilter *filter;
|
||||
GListStore *filters;
|
||||
|
||||
texture = create_texture (self);
|
||||
if (texture == NULL)
|
||||
node = create_node (self);
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_mime_type (filter, "image/png");
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_mime_type (filter, "image/svg+xml");
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_mime_type (filter, "image/tiff");
|
||||
g_list_store_append (filters, filter);
|
||||
g_object_unref (filter);
|
||||
|
||||
dialog = gtk_file_dialog_new ();
|
||||
gtk_file_dialog_set_title (dialog, "");
|
||||
gtk_file_dialog_set_initial_name (dialog, "example.png");
|
||||
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
|
||||
gtk_file_dialog_save (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
NULL,
|
||||
export_image_response_cb, texture);
|
||||
export_image_response_cb, node);
|
||||
g_object_unref (filters);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
@@ -859,6 +1017,19 @@ testcase_save_clicked_cb (GtkWidget *button,
|
||||
}
|
||||
|
||||
text = get_current_text (self->text_buffer);
|
||||
{
|
||||
GBytes *bytes;
|
||||
GskRenderNode *node;
|
||||
gsize size;
|
||||
|
||||
bytes = g_bytes_new_take (text, strlen (text) + 1);
|
||||
node = gsk_render_node_deserialize (bytes, NULL, NULL);
|
||||
g_bytes_unref (bytes);
|
||||
bytes = gsk_render_node_serialize (node);
|
||||
gsk_render_node_unref (node);
|
||||
text = g_bytes_unref_to_data (bytes, &size);
|
||||
}
|
||||
|
||||
if (!g_file_set_contents (node_file, text, -1, &error))
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (self->testcase_error_label), error->message);
|
||||
|
||||
@@ -178,6 +178,16 @@ Creates a node like `gsk_inset_shadow_node_new()` with the given properties.
|
||||
|
||||
Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
|
||||
|
||||
### mask
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| source | `<node>` | color { } | always |
|
||||
| mode | `<blend-mode>` | alpha | non-default |
|
||||
| mask | `<node>` | color { } | always |
|
||||
|
||||
Creates a node like `gsk_mask_node_new()` with the given properties.
|
||||
|
||||
### opacity
|
||||
|
||||
| property | syntax | default | printed |
|
||||
|
||||
@@ -69,7 +69,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
|
||||
else
|
||||
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
|
||||
'widget-factory.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
endif
|
||||
|
||||
|
||||
@@ -678,11 +678,10 @@ Interfaces must have the following macros:
|
||||
|
||||
### Memory allocation
|
||||
|
||||
When dynamically allocating data on the heap either use `g_new()` or,
|
||||
if allocating multiple small data structures, `g_slice_new()`.
|
||||
When dynamically allocating data on the heap use `g_new()`.
|
||||
|
||||
Public structure types should always be returned after being zero-ed,
|
||||
either explicitly for each member, or by using `g_new0()` or `g_slice_new0()`.
|
||||
either explicitly for each member, or by using `g_new0()`.
|
||||
|
||||
### Macros
|
||||
|
||||
|
||||
@@ -6,22 +6,15 @@ Slug: broadway
|
||||
The GDK Broadway backend provides support for displaying GTK applications in
|
||||
a web browser, using HTML5 and web sockets.
|
||||
|
||||
To run your application in this way, select the Broadway backend by setting
|
||||
`GDK_BACKEND=broadway`. Then you can make your application appear in a web
|
||||
browser by pointing it at `http://127.0.0.1:8080`. Note that you need to
|
||||
enable web sockets in your web browser.
|
||||
|
||||
You can choose a different port from the default 8080 by setting the
|
||||
`BROADWAY_DISPLAY` environment variable to the port that you want to use.
|
||||
|
||||
It is also possible to use multiple GTK applications in the same web browser
|
||||
window, by using the Broadway server, `gtk4-broadwayd`, that ships with GTK.
|
||||
To start the Broadway server use:
|
||||
To run your application in this way, first run the broadway server,
|
||||
`gtk-broadwayd`, that ships with GTK:
|
||||
|
||||
```
|
||||
gtk4-broadwayd :5
|
||||
```
|
||||
|
||||
The server expects the colon-prefixed display number as a commandline argument.
|
||||
|
||||
Then point your web browser at `http://127.0.0.1:8085`.
|
||||
|
||||
Once the Broadway server is running, you can start your applications like
|
||||
@@ -31,6 +24,8 @@ this:
|
||||
GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk4-demo
|
||||
```
|
||||
|
||||
Multiple applications can be presented in the same web browser window.
|
||||
|
||||
## Broadway-specific environment variables
|
||||
|
||||
### `BROADWAY_DISPLAY`
|
||||
|
||||
@@ -239,14 +239,14 @@ control whether Vulkan should be used.
|
||||
### `media-gstreamer` and `media-ffmpeg`
|
||||
|
||||
By default, GTK will try to build the gstreamer backend for
|
||||
media playback support. These option can be used to explicitly
|
||||
media playback support. These options can be used to explicitly
|
||||
control which media backends should be built.
|
||||
|
||||
### `print-cups`
|
||||
### `print-cups` and `print-cpdb`
|
||||
|
||||
By default, GTK will try to build various print backends
|
||||
if their dependencies are found. This option can be used
|
||||
to explicitly control whether the cups print backend should be built.
|
||||
By default, GTK will try to build the cups and file print backends
|
||||
if their dependencies are found. These options can be used to
|
||||
explicitly control which print backends should be built.
|
||||
|
||||
### `cloudproviders`
|
||||
|
||||
|
||||
@@ -66,6 +66,10 @@ You can compile the program above with GCC using:
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
|
||||
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
|
||||
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
|
||||
others in this documentation.
|
||||
For more information on how to compile a GTK application, please
|
||||
refer to the [Compiling GTK Applications](compiling.html)
|
||||
section in this reference.
|
||||
|
||||
@@ -33,6 +33,11 @@ Validation
|
||||
The ``validate`` command validates the given UI definition file and reports
|
||||
errors to ``stderr``.
|
||||
|
||||
Note that there are limitations to the validation that can be done for templates,
|
||||
since they are closely tied to the class_init function they are used in.
|
||||
If your UI file uses types from third-party libraries, it may help to add those
|
||||
libraries to the `LD_PRELOAD` environment variable.
|
||||
|
||||
``--deprecations``
|
||||
|
||||
Warn about uses of deprecated types in the UI definition file.
|
||||
|
||||
@@ -7,37 +7,50 @@ the question you have, this list is a good place to start.
|
||||
|
||||
## General Questions
|
||||
|
||||
1. How do I get started with GTK?
|
||||
* How do I get started with GTK?
|
||||
|
||||
The GTK [website](https://www.gtk.org) offers some
|
||||
[tutorials](https://www.gtk.org/documentation.php) and other documentation
|
||||
(most of it about GTK 2.x and 3.x, but still somewhat applicable). This
|
||||
reference manual also contains a introductory
|
||||
This reference manual also contains a introductory
|
||||
[Getting Started](#gtk-getting-started) part.
|
||||
|
||||
More documentation ranging from whitepapers to online books can be found at
|
||||
the [GNOME developer's site](https://developer.gnome.org). After studying these
|
||||
materials you should be well prepared to come back to this reference manual for details.
|
||||
|
||||
2. Where can I get help with GTK, submit a bug report, or make a feature request?
|
||||
* Where can I get help with GTK, submit a bug report, or make a feature request?
|
||||
|
||||
See the [documentation](#gtk-resources) on this topic.
|
||||
|
||||
3. How do I port from one GTK version to another?
|
||||
* How do I port from one GTK version to another?
|
||||
|
||||
See the [migration guide](#migrating). You may also find useful information in
|
||||
the documentation for specific widgets and functions. If you have a question not
|
||||
covered in the manual, feel free to ask, and please
|
||||
Every major version of GTK comes with a [migration guide](#migrating). You may also
|
||||
find useful information in the documentation for specific widgets and functions. If
|
||||
you have a question not covered in the manual, feel free to ask, and please
|
||||
[file a bug report](https://gitlab.gnome.org/GNOME/gtk/issues/new) against the
|
||||
documentation.
|
||||
|
||||
4. How does memory management work in GTK? Should I free data returned from functions?
|
||||
* Should I maintain parallel versions of my UI in GTK x and GTK y?
|
||||
|
||||
At the end of the day, that is up to you.
|
||||
|
||||
Our experience is that it is a lot of work, and usually not a good idea.
|
||||
|
||||
If you are not ready to make the jump to the next major version of GTK,
|
||||
it is perfectly fine to stick with the stable release. We maintain them
|
||||
for that reason.
|
||||
|
||||
* How does memory management work in GTK? Should I free data returned from functions?
|
||||
|
||||
See the documentation for `GObject` and `GInitiallyUnowned`. For `GObject` note
|
||||
specifically `g_object_ref()` and `g_object_unref()`. `GInitiallyUnowned` is a
|
||||
subclass of `GObject` so the same points apply, except that it has a "floating"
|
||||
state (explained in its documentation).
|
||||
|
||||
In a widget tree, each container owns a reference to its children. The root
|
||||
object (typically a `GtkWindow`) is owned by GTK. GTK will drop its reference
|
||||
when you call [method@Gtk.Window.destroy].
|
||||
|
||||
For strings returned from functions, they will be declared "const" if they should
|
||||
not be freed. Non-const strings should be freed with `g_free()`. Arrays follow the
|
||||
same rule. If you find an undocumented exception to the rules, please
|
||||
@@ -46,7 +59,7 @@ the question you have, this list is a good place to start.
|
||||
The transfer annotations for gobject-introspection that are part of the
|
||||
documentation can provide useful hints for memory handling semantics as well.
|
||||
|
||||
5. Why does my program leak memory, if I destroy a widget immediately
|
||||
* Why does my program leak memory, if I destroy a widget immediately
|
||||
after creating it?
|
||||
|
||||
If `GtkFoo` isn't a toplevel window, then
|
||||
@@ -69,7 +82,7 @@ the question you have, this list is a good place to start.
|
||||
the initial floating reference and you don't have to worry about reference
|
||||
counting at all ... just remove the widget from the container to get rid of it.
|
||||
|
||||
6. How do I use GTK with threads?
|
||||
* How do I use GTK with threads?
|
||||
|
||||
GTK requires that all GTK API calls are made from the same thread in which
|
||||
the `GtkApplication` was created, or `gtk_init()` was called (the _main thread_).
|
||||
@@ -79,7 +92,7 @@ the question you have, this list is a good place to start.
|
||||
the results back to the main thread using `g_idle_add()` or `GAsyncQueue`. GIO
|
||||
offers useful tools for such an approach such as `GTask`.
|
||||
|
||||
7. How do I internationalize a GTK program?
|
||||
* How do I internationalize a GTK program?
|
||||
|
||||
Most people use [GNU gettext](https://www.gnu.org/software/gettext/),
|
||||
already required in order to install GLib. On a UNIX or Linux system with
|
||||
@@ -134,7 +147,7 @@ the question you have, this list is a good place to start.
|
||||
|
||||
#define _(x) dgettext (GETTEXT_PACKAGE, x)
|
||||
|
||||
8. How do I use non-ASCII characters in GTK programs ?
|
||||
* How do I use non-ASCII characters in GTK programs ?
|
||||
|
||||
GTK uses [Unicode](http://www.unicode.org) (more exactly UTF-8) for all text.
|
||||
UTF-8 encodes each Unicode codepoint as a sequence of one to six bytes and
|
||||
@@ -217,7 +230,7 @@ the question you have, this list is a good place to start.
|
||||
to call bind_textdomain_codeset() to ensure that translated strings
|
||||
are returned in UTF-8 encoding.
|
||||
|
||||
9. How do I use GTK with C++?
|
||||
* How do I use GTK with C++?
|
||||
|
||||
There are two ways to approach this. The GTK header files use the subset
|
||||
of C that's also valid C++, so you can simply use the normal GTK API
|
||||
@@ -242,19 +255,23 @@ the question you have, this list is a good place to start.
|
||||
|
||||
There are very few functions that require this cast, however.
|
||||
|
||||
10. How do I use GTK with other non-C languages?
|
||||
* How do I use GTK with other non-C languages?
|
||||
|
||||
See the list of [language bindings](https://www.gtk.org/language-bindings.php)
|
||||
on the GTK [website](https://www.gtk.org).
|
||||
|
||||
11. How do I load an image or animation from a file?
|
||||
* How do I load an image or animation from a file?
|
||||
|
||||
To load an image file straight into a display widget, use
|
||||
[ctor@Gtk.Image.new_from_file]. To load an image for another purpose, use
|
||||
[ctor@Gdk.Texture.new_from_file]. To load a video from a file, use
|
||||
[ctor@Gtk.MediaFile.new_for_file].
|
||||
[ctor@Gtk.Picture.new_for_file] or [ctor@GTk.Picture.new_for_filename].
|
||||
To load an image for another purpose, use [ctor@Gdk.Texture.new_from_file].
|
||||
To load a video from a file, use [ctor@Gtk.MediaFile.new_for_file].
|
||||
|
||||
12. How do I draw text?
|
||||
* How do I draw text?
|
||||
|
||||
If you just want to put text into your user interface somewhere, it is
|
||||
usually easiest to just use one of ready-made widgets for this purpose,
|
||||
such as [class@Gtk.Label].
|
||||
|
||||
To draw a piece of text onto a cairo surface, use a Pango layout and
|
||||
[func@PangoCairo.show_layout].
|
||||
@@ -272,7 +289,7 @@ the question you have, this list is a good place to start.
|
||||
To draw a piece of text in a widget [vfunc@Gtk.Widget.snapshot] implementation,
|
||||
use [method@Gtk.Snapshot.append_layout].
|
||||
|
||||
13. How do I measure the size of a piece of text?
|
||||
* How do I measure the size of a piece of text?
|
||||
|
||||
To obtain the size of a piece of text, use a Pango layout and
|
||||
[method@Pango.Layout.get_pixel_size], using code like the following:
|
||||
@@ -287,7 +304,7 @@ the question you have, this list is a good place to start.
|
||||
See also the [Layout Objects](https://developer.gnome.org/pango/stable/pango-Layout-Objects.html)
|
||||
section of the [Pango documentation](https://developer.gnome.org/pango/stable/).
|
||||
|
||||
14. Why are types not registered if I use their `GTK_TYPE_BLAH` macro?
|
||||
* Why are types not registered if I use their `GTK_TYPE_BLAH` macro?
|
||||
|
||||
The %GTK_TYPE_BLAH macros are defined as calls to gtk_blah_get_type(), and
|
||||
the `_get_type()` functions are declared as %G_GNUC_CONST which allows the
|
||||
@@ -298,14 +315,14 @@ the question you have, this list is a good place to start.
|
||||
|
||||
g_type_ensure (GTK_TYPE_BLAH);
|
||||
|
||||
15. How do I create a transparent toplevel window?
|
||||
* How do I create a transparent toplevel window?
|
||||
|
||||
Any toplevel window can be transparent. It is just a matter of setting a
|
||||
transparent background in the CSS style for it.
|
||||
|
||||
## Which widget should I use...
|
||||
|
||||
16. ...for lists and trees?
|
||||
* ...for lists and trees?
|
||||
|
||||
This question has different answers, depending on the size of the dataset
|
||||
and the required formatting flexibility.
|
||||
@@ -321,7 +338,7 @@ the question you have, this list is a good place to start.
|
||||
and widgetry inside the list, then you probably want to use a [class@Gtk.ListBox],
|
||||
which uses regular widgets for display.
|
||||
|
||||
17. ...for multi-line text display or editing?
|
||||
* ...for multi-line text display or editing?
|
||||
|
||||
See the [text widget overview](#TextWidget) -- you should use the
|
||||
[class@Gtk.TextView] widget.
|
||||
@@ -330,7 +347,7 @@ the question you have, this list is a good place to start.
|
||||
of course. It can be made selectable with [method@Gtk.Label.set_selectable]. For a
|
||||
single-line text entry, see [class@Gtk.Entry].
|
||||
|
||||
18. ...to display an image or animation?
|
||||
* ...to display an image or animation?
|
||||
|
||||
GTK has two widgets that are dedicated to displaying images. [class@Gtk.Image], for
|
||||
small, fixed-size icons and [class@Gtk.Picture] for content images.
|
||||
@@ -346,17 +363,14 @@ the question you have, this list is a good place to start.
|
||||
mediafile = gtk_media_file_new_for_filename ("example.webm");
|
||||
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (mediafile));
|
||||
|
||||
19. ...for presenting a set of mutually-exclusive choices, where Windows
|
||||
* ...for presenting a set of mutually-exclusive choices, where Windows
|
||||
would use a combo box?
|
||||
|
||||
With GTK, a [class@Gtk.ComboBox] is the recommended widget to use for this use case.
|
||||
If you need an editable text entry, use the [property@Gtk.ComboBox:has-entry] property.
|
||||
|
||||
A newer alternative is [class@Gtk.DropDown].
|
||||
With GTK, a [class@Gtk.DropDown] is the recommended widget to use for this use case.
|
||||
|
||||
## Questions about GtkWidget
|
||||
|
||||
20. How do I change the color of a widget?
|
||||
* How do I change the color of a widget?
|
||||
|
||||
The background color of a widget is determined by the CSS style that applies
|
||||
to it. To change that, you can set style classes on the widget, and provide
|
||||
@@ -364,7 +378,7 @@ the question you have, this list is a good place to start.
|
||||
[method@Gtk.CssProvider.load_from_file] and its variants.
|
||||
See [method@Gtk.StyleContext.add_provider].
|
||||
|
||||
21. How do I change the font of a widget?
|
||||
* How do I change the font of a widget?
|
||||
|
||||
If you want to make the text of a label larger, you can use
|
||||
gtk_label_set_markup():
|
||||
@@ -388,14 +402,14 @@ the question you have, this list is a good place to start.
|
||||
of this approach is that users can then override the font you have chosen.
|
||||
See the `GtkStyleContext` documentation for more discussion.
|
||||
|
||||
22. How do I disable/ghost/desensitize a widget?
|
||||
* How do I disable/ghost/desensitize a widget?
|
||||
|
||||
In GTK a disabled widget is termed _insensitive_.
|
||||
See [method@Gtk.Widget.set_sensitive].
|
||||
|
||||
## GtkTextView questions
|
||||
|
||||
23. How do I get the contents of the entire text widget as a string?
|
||||
* How do I get the contents of the entire text widget as a string?
|
||||
|
||||
See [method@Gtk.TextBuffer.get_bounds] and [method@Gtk.TextBuffer.get_text]
|
||||
or [method@Gtk.TextIter.get_text].
|
||||
@@ -410,14 +424,14 @@ the question you have, this list is a good place to start.
|
||||
/* use text */
|
||||
g_free (text);
|
||||
|
||||
24. How do I make a text widget display its complete contents in a specific font?
|
||||
* How do I make a text widget display its complete contents in a specific font?
|
||||
|
||||
If you use [method@Gtk.TextBuffer.insert_with_tags] with appropriate tags to
|
||||
select the font, the inserted text will have the desired appearance, but
|
||||
text typed in by the user before or after the tagged block will appear in
|
||||
the default style.
|
||||
|
||||
25. How do I make a text view scroll to the end of the buffer automatically ?
|
||||
* How do I make a text view scroll to the end of the buffer automatically ?
|
||||
|
||||
A good way to keep a text buffer scrolled to the end is to place a
|
||||
[mark](#GtkTextMark) at the end of the buffer, and give it right gravity.
|
||||
@@ -432,21 +446,21 @@ the question you have, this list is a good place to start.
|
||||
|
||||
## GtkTreeView questions
|
||||
|
||||
26. How do I associate some data with a row in the tree?
|
||||
* How do I associate some data with a row in the tree?
|
||||
|
||||
Remember that the [iface@Gtk.TreeModel] columns don't necessarily have to be
|
||||
displayed. So you can put non-user-visible data in your model just
|
||||
like any other data, and retrieve it with [method@Gtk.TreeModel.get].
|
||||
See the [tree widget overview](#TreeWidget).
|
||||
|
||||
27. How do I put an image and some text in the same column?
|
||||
* How do I put an image and some text in the same column?
|
||||
|
||||
You can pack more than one [class@Gtk.CellRenderer] into a single [class@Gtk.TreeViewColumn]
|
||||
using [method@Gtk.TreeViewColumn.pack_start] or [method@Gtk.TreeViewColumn.pack_end].
|
||||
So pack both a [class@Gtk.CellRendererPixbuf] and a [class@Gtk.CellRendererText] into the
|
||||
column.
|
||||
|
||||
28. I can set data easily on my [class@Gtk.TreeStore] or [class@Gtk.ListStore] models using
|
||||
* I can set data easily on my [class@Gtk.TreeStore] or [class@Gtk.ListStore] models using
|
||||
[method@Gtk.ListStore.set] and [method@Gtk.TreeStore.set], but can't read it back?
|
||||
|
||||
Both the [class@Gtk.TreeStore] and the [class@Gtk.ListStore] implement the [iface@Gtk.TreeModel]
|
||||
@@ -454,7 +468,7 @@ the question you have, this list is a good place to start.
|
||||
implements. The easiest way to read a set of data back is to use
|
||||
[method@Gtk.TreeModel.get].
|
||||
|
||||
29. How do I change the way that numbers are formatted by `GtkTreeView`?
|
||||
* How do I change the way that numbers are formatted by `GtkTreeView`?
|
||||
|
||||
Use [method@Gtk.TreeView.insert_column_with_data_func] or
|
||||
[method@Gtk.TreeViewColumn.set_cell_data_func] and do the conversion
|
||||
@@ -528,19 +542,21 @@ the question you have, this list is a good place to start.
|
||||
(gpointer)DOUBLE_COLUMN, NULL);
|
||||
}
|
||||
|
||||
30. How do I hide the expander arrows in my tree view?
|
||||
* How do I hide the expander arrows in my tree view?
|
||||
|
||||
Set the expander-column property of the tree view to a hidden column.
|
||||
See [method@Gtk.TreeView.set_expander_column] and [method@Gtk.TreeViewColumn.set_visible].
|
||||
|
||||
## Using cairo with GTK
|
||||
|
||||
31. How do I use cairo to draw in GTK applications?
|
||||
* How do I use cairo to draw in GTK applications?
|
||||
|
||||
Use [method@Gtk.Snapshot.append_cairo] in your [vfunc@Gtk.Widget.snapshot] vfunc
|
||||
to obtain a cairo context and draw with that.
|
||||
[class@Gtk.DrawingArea] is a ready-made widget for drawing with cairo.
|
||||
|
||||
32. Can I improve the performance of my application by using another backend
|
||||
If you implement a custom widget, use [method@Gtk.Snapshot.append_cairo]
|
||||
in your [vfunc@Gtk.Widget.snapshot] vfunc to obtain a cairo context and draw with that.
|
||||
|
||||
* Can I improve the performance of my application by using another backend
|
||||
of cairo (such as GL)?
|
||||
|
||||
No. Most drawing in GTK is not done via cairo anymore (but instead
|
||||
@@ -551,7 +567,7 @@ the question you have, this list is a good place to start.
|
||||
|
||||
If you are interested in using GL for your own drawing, see [class@Gtk.GLArea].
|
||||
|
||||
33. Can I use cairo to draw on a `GdkPixbuf`?
|
||||
* Can I use cairo to draw on a `GdkPixbuf`?
|
||||
|
||||
No. The cairo image surface does not support the pixel format used by `GdkPixbuf`.
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ Each state name is part of the `GtkAccessibleState` enumeration.
|
||||
| %GTK_ACCESSIBLE_STATE_INVALID | “aria-invalid” | `GtkAccessibleInvalidState` | Set when a widget is showing an error |
|
||||
| %GTK_ACCESSIBLE_STATE_PRESSED | “aria-pressed” | `GtkAccessibleTristate` | Indicates the current state of a [class@Gtk.ToggleButton] |
|
||||
| %GTK_ACCESSIBLE_STATE_SELECTED | “aria-selected” | boolean or undefined | Set when a widget is selected |
|
||||
| %GTK_ACCESSIBLE_STATE_VISITED | N/A | boolean or undefined | Set when a link-like widget is visited |
|
||||
|
||||
#### List of accessible properties
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ Lists are intended to be used whenever developers want to display many objects
|
||||
in roughly the same way.
|
||||
|
||||
Lists are perfectly fine to be used for very short list of only 2 or 3 elements,
|
||||
but generally scale fine to millions of items. Of course, the larger the list
|
||||
grows, the more care needs to be taken to choose the right data structures to
|
||||
keep things running well.
|
||||
but generally scale to millions of items. Of course, the larger the list grows,
|
||||
the more care needs to be taken to choose the right data structures to keep things
|
||||
running well.
|
||||
|
||||
Lists are meant to be used with changing data, both with the items itself changing
|
||||
as well as the list adding and removing items. Of course, they work just as well
|
||||
@@ -26,12 +26,14 @@ have a specific meaning in this context.
|
||||
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists.
|
||||
Examples of these widgets would be [`class@Gtk.ListView`] or [`class@Gtk.GridView`].
|
||||
|
||||
Views display data from a **_model_**. A model is a [`iface@Gio.ListModel`] and
|
||||
models can be provided in 3 ways or combinations thereof:
|
||||
Views display data from a **_model_**. Models implement the [`iface@Gio.ListModel`]
|
||||
interface and can be provided in a variety of ways:
|
||||
|
||||
* Many list models implementations already exist. There are models that provide
|
||||
specific data, like `GtkDirectoryList`. And there are models like `GListStore`
|
||||
that allow building lists manually.
|
||||
* List model implementations for many specific types of data already exist, for
|
||||
example `GtkDirectoryList` or `GtkStringList`.
|
||||
|
||||
* There are generic list model implementations like`GListStore` that allow building
|
||||
lists of arbitrary objects.
|
||||
|
||||
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
|
||||
modify, adapt or combine other models.
|
||||
@@ -47,8 +49,8 @@ The elements in a model are called **_items_**. All items are
|
||||
|
||||
Every item in a model has a **_position_** which is the unsigned integer that
|
||||
describes where in the model the item is located. The first item in a model is
|
||||
at position 0. The position of an item can of course change as other items are
|
||||
added or removed from the model.
|
||||
at position 0. The position of an item can change as other items are added or
|
||||
removed from the model.
|
||||
|
||||
It is important to be aware of the difference between items and positions
|
||||
because the mapping from position to item is not permanent, so developers
|
||||
@@ -71,10 +73,10 @@ with the item managed by the listitem. Finding a suitable factory implementation
|
||||
for the data displayed, the programming language and development environment
|
||||
is an important task that can simplify setting up the view tremendously.
|
||||
|
||||
Views support selections via a **_selection model_**. A selection model is an
|
||||
implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
|
||||
[`iface@Gio.ListModel`] interface that allows marking each item in a model as either
|
||||
selected or not selected. Just like regular models, this can be implemented
|
||||
Views support selections via a **_selection model_**. A selection model is
|
||||
an implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
|
||||
[`iface@Gio.ListModel`] interface that allows marking each item in a model as
|
||||
either selected or not selected. Just like regular models, this can be implemented
|
||||
either by implementing `GtkSelectionModel` directly or by wrapping a model with
|
||||
one of the GTK models provided for this purposes, such as [`class@Gtk.NoSelection`]
|
||||
or [`class@Gtk.SingleSelection`].
|
||||
@@ -87,19 +89,18 @@ item is exposed in the listitem via the [`property@Gtk.ListItem:selected`] prope
|
||||
|
||||
Views and listitems also support activation. Activation means that double
|
||||
clicking or pressing enter while inside a focused row will cause the view
|
||||
to emit and activation signal such as [`signal@Gtk.ListView::activate`]. This
|
||||
provides an easy way to set up lists, but can also be turned off on listitems
|
||||
if undesired.
|
||||
to emit a signal such as [`signal@Gtk.ListView::activate`]. This provides an
|
||||
easy way to set up lists, but can also be turned off on listitems if undesired.
|
||||
|
||||
Both selections and activation are supported among other things via widget
|
||||
[actions](#actions-overview). This allows developers to add widgets to their
|
||||
lists that cause selections to change or to trigger activation via
|
||||
the [`iface@Gtk.Actionable`] interface. For a list of all supported actions see
|
||||
the relevant documentation.
|
||||
lists that cause selections to change or to trigger activation via the
|
||||
[`iface@Gtk.Actionable`] interface. For a list of all supported actions
|
||||
see the relevant documentation.
|
||||
|
||||
## Behind the scenes
|
||||
|
||||
While for short lists it is not a problem to instantiate widgets for every
|
||||
While it is not a problem for short lists to instantiate widgets for every
|
||||
item in the model, once lists grow to thousands or millions of elements, this
|
||||
gets less feasible. Because of this, the views only create a limited amount of
|
||||
listitems and recycle them by binding them to new items. In general, views try
|
||||
@@ -107,7 +108,7 @@ to keep listitems available only for the items that can actually be seen on
|
||||
screen.
|
||||
|
||||
While this behavior allows views to scale effortlessly to huge lists, it has a
|
||||
few implication on what can be done with views. For example, it is not possible
|
||||
few implications for what can be done with views. For example, it is not possible
|
||||
to query a view for a listitem used for a certain position - there might not be
|
||||
one and even if there is, that listitem might soon be recycled for a new
|
||||
position.
|
||||
@@ -161,9 +162,9 @@ in particular `GListModel` do not. This was a design choice because the common
|
||||
use case is displaying lists and not trees and it greatly simplifies the API
|
||||
interface provided.
|
||||
|
||||
However, GTK provides functionality to make trees look and behave like lists
|
||||
for the people who still want to display lists. This is achieved by using
|
||||
the [`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
|
||||
However, GTK provides functionality to make lists look and behave like trees
|
||||
for use cases that require trees. This is achieved by using the
|
||||
[`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
|
||||
[`class@Gtk.TreeExpander`] widget can then be used inside a listitem to allow
|
||||
users to expand and collapse rows and provide a similar experience to
|
||||
`GtkTreeView`.
|
||||
@@ -174,26 +175,26 @@ on the topic.
|
||||
## List styles
|
||||
|
||||
One of the advantages of the new list widgets over `GtkTreeView` and cell
|
||||
renderers is that they are fully themable using GTK CSS. This provides a
|
||||
lot of flexibility. The themes that ship with GTK provide a few predefined
|
||||
list styles that can be used in many situations:
|
||||
renderers is that they are styleable using GTK CSS. This provides a lot of
|
||||
flexibility. The themes that ship with GTK provide a few predefined list
|
||||
styles that can be used in many situations:
|
||||
|
||||

|
||||
|
||||
This style of list is low density, spacious and uses an outline focus ring.
|
||||
It is suitable for lists of controls, e.g. in preference dialogs or
|
||||
This _rich list_ style is low density, spacious and uses an outline focus
|
||||
ring. It is suitable for lists of controls, e.g. in preference dialogs or
|
||||
settings panels. Use the `.rich-list` style class.
|
||||
|
||||

|
||||
|
||||
This style of list is medium density, using a full background to indicate
|
||||
focus and selection. Use the `.navigation-sidebar` style class.
|
||||
The _sidebar_ style of list is medium density, using a full background to
|
||||
indicate focus and selection. Use the `.navigation-sidebar` style class.
|
||||
|
||||

|
||||
|
||||
This style of list is a high density table, similar in style to a traditional
|
||||
treeview. Individual cells can be selectable and editable. Use the `.data-table`
|
||||
style class.
|
||||
The _data table_ style of list is a high density table, similar in style to a
|
||||
traditional treeview. Individual cells can be selectable and editable. Use
|
||||
the `.data-table` style class.
|
||||
|
||||
## Comparison to GtkTreeView
|
||||
|
||||
@@ -202,20 +203,19 @@ compares to the way they know. This section will try to outline the similarities
|
||||
and differences between the two.
|
||||
|
||||
This new approach tries to provide roughly the same functionality as the old
|
||||
approach but often uses a very different approach to achieve these goals.
|
||||
approach but often uses a very different way to achieve these goals.
|
||||
|
||||
The main difference and one of the primary reasons for this new development is
|
||||
that items can be displayed using regular widgets and `GtkCellRenderer` is no
|
||||
longer necessary. This allows all benefits that widgets provide, such as complex
|
||||
layout and animating widgets and not only makes cell renderers obsolete, but
|
||||
also `GtkCellArea`.
|
||||
that items can be displayed using regular widgets and the separate cell renderer
|
||||
machinery is no longer necessary. This allows all benefits that widgets provide,
|
||||
such as complex layout, animations and CSS styling.
|
||||
|
||||
The other big difference is the massive change to the data model. `GtkTreeModel`
|
||||
was a rather complex interface for a tree data structure and `GListModel` was
|
||||
deliberately designed to be a simple data structure for lists only. (See
|
||||
was a rather complex interface for a tree data structure. `GListModel` is
|
||||
deliberately designed to be a very simple data structure for lists only. (See
|
||||
[above](#displaying-trees)) for how to still do trees with this new model.)
|
||||
Another big change is that the new model allows for bulk changes via
|
||||
the `GListModel::items-changed` signal while `GtkTreeModel` only allows a single
|
||||
Another big change is that the new model allows for bulk changes via the
|
||||
`GListModel::items-changed` signal while `GtkTreeModel` only allows a single
|
||||
item to change at once. The goal here is of course to encourage implementation
|
||||
of custom list models.
|
||||
|
||||
@@ -231,8 +231,8 @@ via custom code in each widget, selection state is now meant to be managed by
|
||||
the selection models. In particular this allows for complex use cases with
|
||||
specialized requirements.
|
||||
|
||||
Finally here's a quick list of equivalent functionality to look for when
|
||||
transitioning code for easy lookup:
|
||||
Finally here's a quick comparison chart of equivalent functionality to look for
|
||||
when transitioning code:
|
||||
|
||||
| Old | New |
|
||||
| -------------------- | ------------------------------------------------------- |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app2_resources = gnome.compile_resources('exampleapp2_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('exampleapp2',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app3_resources = gnome.compile_resources('exampleapp3_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('exampleapp3',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app3_resources,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app4_resources = gnome.compile_resources('exampleapp4_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('exampleapp4',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app4_resources,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app5_resources = gnome.compile_resources('exampleapp5_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app5_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app6_resources = gnome.compile_resources('exampleapp6_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app6_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app7_resources = gnome.compile_resources('exampleapp7_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app7_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app8_resources = gnome.compile_resources('exampleapp8 resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app8_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app9_resources = gnome.compile_resources('exampleapp9_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app9_schemas = gnome.compile_schemas()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
bp_resources = gnome.compile_resources('bloatpad_resources',
|
||||
'bloatpad.gresources.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('bloatpad', 'bloatpad.c', bp_resources, dependencies: libgtk_dep, c_args: common_cflags)
|
||||
|
||||
@@ -1574,7 +1574,8 @@ broadway_server_query_mouse (BroadwayServer *server,
|
||||
|
||||
void
|
||||
broadway_server_destroy_surface (BroadwayServer *server,
|
||||
int id)
|
||||
int id,
|
||||
gboolean disconnected)
|
||||
{
|
||||
BroadwaySurface *surface;
|
||||
gint32 transient_for = -1;
|
||||
@@ -1589,8 +1590,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
server->pointer_grab_surface_id = -1;
|
||||
|
||||
if (server->output)
|
||||
broadway_output_destroy_surface (server->output,
|
||||
id);
|
||||
broadway_output_destroy_surface (server->output, id);
|
||||
|
||||
surface = broadway_server_lookup_surface (server, id);
|
||||
if (surface != NULL)
|
||||
@@ -1604,7 +1604,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
broadway_surface_free (server, surface);
|
||||
}
|
||||
|
||||
if (transient_for != -1)
|
||||
if (transient_for != -1 && !disconnected)
|
||||
{
|
||||
surface = broadway_server_lookup_surface (server, transient_for);
|
||||
if (surface != NULL)
|
||||
|
||||
@@ -93,7 +93,8 @@ guint32 broadway_server_new_surface (BroadwayServer *
|
||||
int width,
|
||||
int height);
|
||||
void broadway_server_destroy_surface (BroadwayServer *server,
|
||||
int id);
|
||||
int id,
|
||||
gboolean disconnected);
|
||||
gboolean broadway_server_surface_show (BroadwayServer *server,
|
||||
int id);
|
||||
gboolean broadway_server_surface_hide (BroadwayServer *server,
|
||||
|
||||
@@ -101,8 +101,7 @@ client_disconnected (BroadwayClient *client)
|
||||
}
|
||||
|
||||
for (l = client->surfaces; l != NULL; l = l->next)
|
||||
broadway_server_destroy_surface (server,
|
||||
GPOINTER_TO_UINT (l->data));
|
||||
broadway_server_destroy_surface (server, GPOINTER_TO_UINT (l->data), TRUE);
|
||||
g_list_free (client->surfaces);
|
||||
client->surfaces = NULL;
|
||||
|
||||
@@ -268,7 +267,7 @@ client_handle_request (BroadwayClient *client,
|
||||
client->surfaces =
|
||||
g_list_remove (client->surfaces,
|
||||
GUINT_TO_POINTER (request->destroy_surface.id));
|
||||
broadway_server_destroy_surface (server, request->destroy_surface.id);
|
||||
broadway_server_destroy_surface (server, request->destroy_surface.id, FALSE);
|
||||
break;
|
||||
case BROADWAY_REQUEST_SHOW_SURFACE:
|
||||
broadway_server_surface_show (server, request->show_surface.id);
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <gdk/gdkdisplaymanager.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdragsurface.h>
|
||||
#include <gdk/gdkdragsurfacesize.h>
|
||||
#include <gdk/gdkdrawcontext.h>
|
||||
#include <gdk/gdkdrop.h>
|
||||
#include <gdk/gdkenums.h>
|
||||
@@ -69,6 +70,7 @@
|
||||
#include <gdk/gdksnapshot.h>
|
||||
#include <gdk/gdksurface.h>
|
||||
#include <gdk/gdktexture.h>
|
||||
#include <gdk/gdktexturedownloader.h>
|
||||
#include <gdk/gdktoplevel.h>
|
||||
#include <gdk/gdktoplevellayout.h>
|
||||
#include <gdk/gdktoplevelsize.h>
|
||||
|
||||
@@ -750,7 +750,7 @@ static void
|
||||
free_value (gpointer value)
|
||||
{
|
||||
g_value_unset (value);
|
||||
g_slice_free (GValue, value);
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -771,7 +771,7 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
|
||||
task = g_task_new (clipboard, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, source_tag);
|
||||
value = g_slice_new0 (GValue);
|
||||
value = g_new0 (GValue, 1);
|
||||
g_value_init (value, type);
|
||||
g_task_set_task_data (task, value, free_value);
|
||||
|
||||
|
||||
@@ -410,7 +410,7 @@ gdk_content_register_deserializer (const char *mime_type,
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (deserialize != NULL);
|
||||
|
||||
deserializer = g_slice_new0 (Deserializer);
|
||||
deserializer = g_new0 (Deserializer, 1);
|
||||
|
||||
deserializer->mime_type = g_intern_string (mime_type);
|
||||
deserializer->type = type;
|
||||
|
||||
@@ -112,7 +112,7 @@ gdk_content_formats_new_take (GType * gtypes,
|
||||
const char **mime_types,
|
||||
gsize n_mime_types)
|
||||
{
|
||||
GdkContentFormats *result = g_slice_new0 (GdkContentFormats);
|
||||
GdkContentFormats *result = g_new0 (GdkContentFormats, 1);
|
||||
result->ref_count = 1;
|
||||
|
||||
result->gtypes = gtypes;
|
||||
@@ -287,7 +287,7 @@ gdk_content_formats_unref (GdkContentFormats *formats)
|
||||
|
||||
g_free (formats->gtypes);
|
||||
g_free (formats->mime_types);
|
||||
g_slice_free (GdkContentFormats, formats);
|
||||
g_free (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,7 +611,7 @@ gdk_content_formats_builder_new (void)
|
||||
{
|
||||
GdkContentFormatsBuilder *builder;
|
||||
|
||||
builder = g_slice_new0 (GdkContentFormatsBuilder);
|
||||
builder = g_new0 (GdkContentFormatsBuilder, 1);
|
||||
builder->ref_count = 1;
|
||||
|
||||
return builder;
|
||||
@@ -665,7 +665,7 @@ gdk_content_formats_builder_unref (GdkContentFormatsBuilder *builder)
|
||||
return;
|
||||
|
||||
gdk_content_formats_builder_clear (builder);
|
||||
g_slice_free (GdkContentFormatsBuilder, builder);
|
||||
g_free (builder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -416,7 +416,7 @@ gdk_content_register_serializer (GType type,
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (serialize != NULL);
|
||||
|
||||
serializer = g_slice_new0 (Serializer);
|
||||
serializer = g_new0 (Serializer, 1);
|
||||
|
||||
serializer->mime_type = g_intern_string (mime_type);
|
||||
serializer->type = type;
|
||||
|
||||
@@ -322,7 +322,7 @@ static void
|
||||
free_pointer_info (GdkPointerSurfaceInfo *info)
|
||||
{
|
||||
g_clear_object (&info->surface_under_pointer);
|
||||
g_slice_free (GdkPointerSurfaceInfo, info);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -834,7 +834,7 @@ _gdk_display_get_pointer_info (GdkDisplay *display,
|
||||
|
||||
if (G_UNLIKELY (!info))
|
||||
{
|
||||
info = g_slice_new0 (GdkPointerSurfaceInfo);
|
||||
info = g_new0 (GdkPointerSurfaceInfo, 1);
|
||||
g_hash_table_insert (display->pointers_info, device, info);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,22 @@
|
||||
|
||||
G_DEFINE_INTERFACE (GdkDragSurface, gdk_drag_surface, GDK_TYPE_SURFACE)
|
||||
|
||||
enum
|
||||
{
|
||||
COMPUTE_SIZE,
|
||||
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
void
|
||||
gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
|
||||
GdkDragSurfaceSize *size)
|
||||
{
|
||||
g_signal_emit (surface, signals[COMPUTE_SIZE], 0, size);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_drag_surface_default_present (GdkDragSurface *drag_surface,
|
||||
int width,
|
||||
@@ -49,6 +65,35 @@ static void
|
||||
gdk_drag_surface_default_init (GdkDragSurfaceInterface *iface)
|
||||
{
|
||||
iface->present = gdk_drag_surface_default_present;
|
||||
|
||||
/**
|
||||
* GdkDragSurface::compute-size:
|
||||
* @surface: a `GdkDragSurface`
|
||||
* @size: (type Gdk.DragSurfaceSize) (out caller-allocates): a
|
||||
* `GdkDragSurfaceSize`
|
||||
*
|
||||
* Emitted when the size for the surface needs to be computed, when it is
|
||||
* present.
|
||||
*
|
||||
* It will normally be emitted during the native surface layout cycle when the
|
||||
* surface size needs to be recomputed.
|
||||
*
|
||||
* It is the responsibility of the drag surface user to handle this signal and
|
||||
* compute the desired size of the surface, storing the computed size in the
|
||||
* [struct@Gdk.DragSurfaceSize] object. Failing to do so will result in an
|
||||
* arbitrary size being used as a result.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
signals[COMPUTE_SIZE] =
|
||||
g_signal_new (I_("compute-size"),
|
||||
GDK_TYPE_DRAG_SURFACE,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DRAG_SURFACE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __GDK_DRAG_SURFACE_PRIVATE_H__
|
||||
|
||||
#include "gdkdragsurface.h"
|
||||
#include "gdkdragsurfacesize.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -15,6 +16,9 @@ struct _GdkDragSurfaceInterface
|
||||
int height);
|
||||
};
|
||||
|
||||
void gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
|
||||
GdkDragSurfaceSize *size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DRAG_SURFACE_PRIVATE_H__ */
|
||||
|
||||
57
gdk/gdkdragsurfacesize.c
Normal file
57
gdk/gdkdragsurfacesize.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
/**
|
||||
* GdkDragSurfaceSize:
|
||||
*
|
||||
* The `GdkDragSurfaceSize` struct contains information that is useful
|
||||
* to compute the size of a drag surface.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
|
||||
G_DEFINE_POINTER_TYPE (GdkDragSurfaceSize, gdk_drag_surface_size)
|
||||
|
||||
void
|
||||
gdk_drag_surface_size_init (GdkDragSurfaceSize *size)
|
||||
{
|
||||
*size = (GdkDragSurfaceSize) { 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_surface_size_set_size:
|
||||
* @size: a `GdkDragSurfaceSize`
|
||||
* @width: the width
|
||||
* @height: the height
|
||||
*
|
||||
* Sets the size the drag surface prefers to be resized to.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
void
|
||||
gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
size->width = width;
|
||||
size->height = height;
|
||||
}
|
||||
42
gdk/gdkdragsurfacesize.h
Normal file
42
gdk/gdkdragsurfacesize.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__GDK_H_INSIDE__) && !defined(GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkDragSurfaceSize GdkDragSurfaceSize;
|
||||
|
||||
#define GDK_TYPE_DRAG_SURFACE_SIZE (gdk_drag_surface_size_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_4_12
|
||||
GType gdk_drag_surface_size_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_12
|
||||
void gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
G_END_DECLS
|
||||
29
gdk/gdkdragsurfacesizeprivate.h
Normal file
29
gdk/gdkdragsurfacesizeprivate.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdkdragsurfacesize.h"
|
||||
|
||||
struct _GdkDragSurfaceSize
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
void gdk_drag_surface_size_init (GdkDragSurfaceSize *size);
|
||||
@@ -767,7 +767,7 @@ static void
|
||||
free_value (gpointer value)
|
||||
{
|
||||
g_value_unset (value);
|
||||
g_slice_free (GValue, value);
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -790,7 +790,7 @@ gdk_drop_read_value_internal (GdkDrop *self,
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, source_tag);
|
||||
value = g_slice_new0 (GValue);
|
||||
value = g_new0 (GValue, 1);
|
||||
g_value_init (value, type);
|
||||
g_task_set_task_data (task, value, free_value);
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ _gdk_frame_timings_new (gint64 frame_counter)
|
||||
{
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
timings = g_slice_new0 (GdkFrameTimings);
|
||||
timings = g_new0 (GdkFrameTimings, 1);
|
||||
timings->ref_count = 1;
|
||||
timings->frame_counter = frame_counter;
|
||||
|
||||
@@ -99,9 +99,7 @@ gdk_frame_timings_unref (GdkFrameTimings *timings)
|
||||
|
||||
timings->ref_count--;
|
||||
if (timings->ref_count == 0)
|
||||
{
|
||||
g_slice_free (GdkFrameTimings, timings);
|
||||
}
|
||||
g_free (timings);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1546,20 +1546,28 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
|
||||
epoxy_has_gl_extension ("OES_vertex_half_float");
|
||||
|
||||
GDK_DISPLAY_DEBUG (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
|
||||
"%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Extensions checked:\n"
|
||||
" - GL_KHR_debug: %s\n"
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - OES_vertex_half_float: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->has_unpack_subimage ? "yes" : "no",
|
||||
priv->has_half_float ? "yes" : "no");
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
int max_texture_size;
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
GDK_DISPLAY_DEBUG (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
|
||||
"%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Max texture size: %d\n"
|
||||
"* Extensions checked:\n"
|
||||
" - GL_KHR_debug: %s\n"
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - OES_vertex_half_float: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
max_texture_size,
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->has_unpack_subimage ? "yes" : "no",
|
||||
priv->has_half_float ? "yes" : "no");
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
@@ -39,7 +38,6 @@ struct _GdkGLTexture {
|
||||
|
||||
GdkGLContext *context;
|
||||
guint id;
|
||||
GLsync sync;
|
||||
|
||||
GdkTexture *saved;
|
||||
|
||||
@@ -65,7 +63,6 @@ drop_gl_resources (GdkGLTexture *self)
|
||||
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
self->sync = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -101,10 +98,6 @@ gdk_gl_texture_invoke_callback (gpointer data)
|
||||
context = gdk_display_get_gl_context (gdk_gl_context_get_display (invoke->self->context));
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
if (invoke->self->sync && context != invoke->self->context)
|
||||
glWaitSync (invoke->self->sync, 0, GL_TIMEOUT_IGNORED);
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, invoke->self->id);
|
||||
|
||||
invoke->func (invoke->self, context, invoke->data);
|
||||
@@ -342,6 +335,7 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
switch (internal_format)
|
||||
{
|
||||
case GL_RGB8:
|
||||
case GL_RGB:
|
||||
texture->format = GDK_MEMORY_R8G8B8;
|
||||
break;
|
||||
|
||||
@@ -446,46 +440,6 @@ gdk_gl_texture_new (GdkGLContext *context,
|
||||
int height,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (id != 0, NULL);
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
|
||||
return gdk_gl_texture_new_with_sync (context, id, NULL, width, height, destroy, data);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_gl_texture_new_with_sync:
|
||||
* @context: a `GdkGLContext`
|
||||
* @id: the ID of a texture that was created with @context
|
||||
* @sync: (nullable): an optional GLsync object
|
||||
* @width: the nominal width of the texture
|
||||
* @height: the nominal height of the texture
|
||||
* @destroy: a destroy notify that will be called when the GL resources
|
||||
* are released
|
||||
* @data: data that gets passed to @destroy
|
||||
*
|
||||
* Creates a new texture for an existing GL texture.
|
||||
*
|
||||
* If @sync is given, consumers of the texture are required to wait on
|
||||
* it before attempting to use the GL texture.
|
||||
*
|
||||
* The GL texture and the sync object must stay alive unmodified until
|
||||
* @destroy is called, which will happen when the GdkTexture object is
|
||||
* finalized, or due to an explicit call of [method@Gdk.GLTexture.release].
|
||||
*
|
||||
* Return value: (transfer full) (type GdkGLTexture): A newly-created
|
||||
* `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_gl_texture_new_with_sync (GdkGLContext *context,
|
||||
guint id,
|
||||
gpointer sync,
|
||||
int width,
|
||||
int height,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data)
|
||||
{
|
||||
GdkGLTexture *self;
|
||||
|
||||
@@ -501,7 +455,6 @@ gdk_gl_texture_new_with_sync (GdkGLContext *context,
|
||||
|
||||
self->context = g_object_ref (context);
|
||||
self->id = id;
|
||||
self->sync = sync;
|
||||
self->destroy = destroy;
|
||||
self->data = data;
|
||||
|
||||
@@ -510,8 +463,3 @@ gdk_gl_texture_new_with_sync (GdkGLContext *context,
|
||||
return GDK_TEXTURE (self);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gdk_gl_texture_get_sync (GdkGLTexture *self)
|
||||
{
|
||||
return self->sync;
|
||||
}
|
||||
|
||||
@@ -9,16 +9,6 @@ G_BEGIN_DECLS
|
||||
|
||||
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
|
||||
guint gdk_gl_texture_get_id (GdkGLTexture *self);
|
||||
gpointer gdk_gl_texture_get_sync (GdkGLTexture *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkTexture * gdk_gl_texture_new_with_sync (GdkGLContext *context,
|
||||
guint id,
|
||||
gpointer sync,
|
||||
int width,
|
||||
int height,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -178,10 +178,10 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
|
||||
g_return_val_if_fail (x >= 0 || x < GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (y >= 0 || y < GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (width > 0 || x + width <= GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (height > 0 || y + height <= GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (x >= 0 && x < GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (y >= 0 && y < GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (width > 0 && x + width <= GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (height > 0 && y + height <= GDK_TEXTURE (source)->height, NULL);
|
||||
|
||||
texture = GDK_TEXTURE (source);
|
||||
bpp = gdk_memory_format_bytes_per_pixel (texture->format);
|
||||
@@ -222,7 +222,7 @@ gdk_memory_texture_from_texture (GdkTexture *texture,
|
||||
data = g_malloc_n (stride, texture->height);
|
||||
|
||||
gdk_texture_do_download (texture, format, data, stride);
|
||||
bytes = g_bytes_new_take (data, stride);
|
||||
bytes = g_bytes_new_take (data, stride * texture->height);
|
||||
result = gdk_memory_texture_new (texture->width,
|
||||
texture->height,
|
||||
format,
|
||||
@@ -233,15 +233,11 @@ gdk_memory_texture_from_texture (GdkTexture *texture,
|
||||
return GDK_MEMORY_TEXTURE (result);
|
||||
}
|
||||
|
||||
const guchar *
|
||||
gdk_memory_texture_get_data (GdkMemoryTexture *self)
|
||||
GBytes *
|
||||
gdk_memory_texture_get_bytes (GdkMemoryTexture *self,
|
||||
gsize *out_stride)
|
||||
{
|
||||
return g_bytes_get_data (self->bytes, NULL);
|
||||
}
|
||||
|
||||
gsize
|
||||
gdk_memory_texture_get_stride (GdkMemoryTexture *self)
|
||||
{
|
||||
return self->stride;
|
||||
*out_stride = self->stride;
|
||||
return self->bytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture *
|
||||
int width,
|
||||
int height);
|
||||
|
||||
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
|
||||
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
|
||||
GBytes * gdk_memory_texture_get_bytes (GdkMemoryTexture *self,
|
||||
gsize *out_stride);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -50,7 +50,7 @@ gdk_io_pipe_new (void)
|
||||
{
|
||||
GdkIOPipe *pipe;
|
||||
|
||||
pipe = g_slice_new0 (GdkIOPipe);
|
||||
pipe = g_new0 (GdkIOPipe, 1);
|
||||
pipe->ref_count = 1;
|
||||
|
||||
g_mutex_init (&pipe->mutex);
|
||||
@@ -76,7 +76,7 @@ gdk_io_pipe_unref (GdkIOPipe *pipe)
|
||||
g_cond_clear (&pipe->cond);
|
||||
g_mutex_clear (&pipe->mutex);
|
||||
|
||||
g_slice_free (GdkIOPipe, pipe);
|
||||
g_free (pipe);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdktexturedownloaderprivate.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
@@ -218,9 +218,9 @@ gdk_pixbuf_get_from_surface (cairo_surface_t *surface,
|
||||
|
||||
static void
|
||||
pixbuf_texture_unref_cb (guchar *pixels,
|
||||
gpointer texture)
|
||||
gpointer bytes)
|
||||
{
|
||||
g_object_unref (texture);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,22 +238,27 @@ pixbuf_texture_unref_cb (guchar *pixels,
|
||||
GdkPixbuf *
|
||||
gdk_pixbuf_get_from_texture (GdkTexture *texture)
|
||||
{
|
||||
GdkMemoryTexture *memtex;
|
||||
GdkTextureDownloader downloader;
|
||||
GBytes *bytes;
|
||||
gsize stride;
|
||||
gboolean alpha;
|
||||
|
||||
alpha = gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_OPAQUE;
|
||||
|
||||
memtex = gdk_memory_texture_from_texture (texture,
|
||||
alpha ? GDK_MEMORY_GDK_PIXBUF_ALPHA
|
||||
: GDK_MEMORY_GDK_PIXBUF_OPAQUE);
|
||||
gdk_texture_downloader_init (&downloader, texture);
|
||||
gdk_texture_downloader_set_format (&downloader,
|
||||
alpha ? GDK_MEMORY_GDK_PIXBUF_ALPHA
|
||||
: GDK_MEMORY_GDK_PIXBUF_OPAQUE);
|
||||
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
|
||||
gdk_texture_downloader_finish (&downloader);
|
||||
|
||||
return gdk_pixbuf_new_from_data (gdk_memory_texture_get_data (memtex),
|
||||
return gdk_pixbuf_new_from_data (g_bytes_get_data (bytes, NULL),
|
||||
GDK_COLORSPACE_RGB,
|
||||
alpha,
|
||||
8,
|
||||
gdk_texture_get_width (GDK_TEXTURE (memtex)),
|
||||
gdk_texture_get_height (GDK_TEXTURE (memtex)),
|
||||
gdk_memory_texture_get_stride (memtex),
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
stride,
|
||||
pixbuf_texture_unref_cb,
|
||||
memtex);
|
||||
bytes);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,12 @@ G_DEFINE_BOXED_TYPE (GdkRGBA, gdk_rgba,
|
||||
GdkRGBA *
|
||||
gdk_rgba_copy (const GdkRGBA *rgba)
|
||||
{
|
||||
return g_slice_dup (GdkRGBA, rgba);
|
||||
GdkRGBA *copy;
|
||||
|
||||
copy = g_new (GdkRGBA, 1);
|
||||
memcpy (copy, rgba, sizeof (GdkRGBA));
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +84,7 @@ gdk_rgba_copy (const GdkRGBA *rgba)
|
||||
void
|
||||
gdk_rgba_free (GdkRGBA *rgba)
|
||||
{
|
||||
g_slice_free (GdkRGBA, rgba);
|
||||
g_free (rgba);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -395,7 +395,7 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
|
||||
bytes = g_bytes_new_with_free_func (gdk_pixbuf_get_pixels (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf)
|
||||
* gdk_pixbuf_get_rowstride (pixbuf),
|
||||
* (gsize) gdk_pixbuf_get_rowstride (pixbuf),
|
||||
g_object_unref,
|
||||
g_object_ref (pixbuf));
|
||||
texture = gdk_memory_texture_new (gdk_pixbuf_get_width (pixbuf),
|
||||
@@ -722,6 +722,9 @@ gdk_texture_download_surface (GdkTexture *texture)
|
||||
* cairo_image_surface_get_stride (surface));
|
||||
* cairo_surface_mark_dirty (surface);
|
||||
* ```
|
||||
*
|
||||
* For more flexible download capabilites, see
|
||||
* [struct@Gdk.TextureDownloader].
|
||||
*/
|
||||
void
|
||||
gdk_texture_download (GdkTexture *texture,
|
||||
@@ -738,9 +741,29 @@ gdk_texture_download (GdkTexture *texture,
|
||||
stride);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_get_format:
|
||||
* @self: a GdkTexture
|
||||
*
|
||||
* Gets the memory format most closely associated with the data of
|
||||
* the texture.
|
||||
*
|
||||
* Note that it may not be an exact match for texture data
|
||||
* stored on the GPU or with compression.
|
||||
*
|
||||
* The format can give an indication about the bit depth and opacity
|
||||
* of the texture and is useful to determine the best format for
|
||||
* downloading the texture.
|
||||
*
|
||||
* Returns: the preferred format for the texture's data
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
GdkMemoryFormat
|
||||
gdk_texture_get_format (GdkTexture *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (self), GDK_MEMORY_DEFAULT);
|
||||
|
||||
return self->format;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdkenums.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
@@ -82,6 +83,8 @@ GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_width (GdkTexture *texture) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_height (GdkTexture *texture) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkMemoryFormat gdk_texture_get_format (GdkTexture *self) G_GNUC_PURE;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_texture_download (GdkTexture *texture,
|
||||
|
||||
268
gdk/gdktexturedownloader.c
Normal file
268
gdk/gdktexturedownloader.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2023 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GdkTextureDownloader:
|
||||
*
|
||||
* The `GdkTextureDownloader` is used to download the contents of a
|
||||
* [class@Gdk.Texture].
|
||||
*
|
||||
* It is intended to be created as a short-term object for a single download,
|
||||
* but can be used for multipe downloads of different textures or with different
|
||||
* settings.
|
||||
*
|
||||
* `GdkTextureDownloader` can be used to convert data between different formats.
|
||||
* Create a `GdkTexture` for the existing format and then download it in a
|
||||
* different format.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdktexturedownloaderprivate.h"
|
||||
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GdkTextureDownloader, gdk_texture_downloader,
|
||||
gdk_texture_downloader_copy,
|
||||
gdk_texture_downloader_free)
|
||||
|
||||
|
||||
void
|
||||
gdk_texture_downloader_init (GdkTextureDownloader *self,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
self->texture = g_object_ref (texture);
|
||||
self->format = GDK_MEMORY_DEFAULT;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_texture_downloader_finish (GdkTextureDownloader *self)
|
||||
{
|
||||
g_object_unref (self->texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_new:
|
||||
* @texture: texture to download
|
||||
*
|
||||
* Creates a new texture downloader for @texture.
|
||||
*
|
||||
* Returns: A new texture downloader
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
GdkTextureDownloader *
|
||||
gdk_texture_downloader_new (GdkTexture *texture)
|
||||
{
|
||||
GdkTextureDownloader *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
|
||||
|
||||
self = g_new (GdkTextureDownloader, 1);
|
||||
gdk_texture_downloader_init (self, texture);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_copy:
|
||||
* @self: the downloader to copy
|
||||
*
|
||||
* Creates a copy of the downloader.
|
||||
*
|
||||
* This function is meant for language bindings.
|
||||
*
|
||||
* Returns: A copy of the downloader
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
GdkTextureDownloader *
|
||||
gdk_texture_downloader_copy (const GdkTextureDownloader *self)
|
||||
{
|
||||
GdkTextureDownloader *copy;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
|
||||
copy = gdk_texture_downloader_new (self->texture);
|
||||
gdk_texture_downloader_set_format (copy, self->format);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_free:
|
||||
* @self: texture downloader to free
|
||||
*
|
||||
* Frees the given downloader and all its associated resources.
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
void
|
||||
gdk_texture_downloader_free (GdkTextureDownloader *self)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
gdk_texture_downloader_finish (self);
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_set_texture:
|
||||
* @self: a texture downloader
|
||||
* @texture: the new texture to download
|
||||
*
|
||||
* Changes the texture the downloader will download.
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
void
|
||||
gdk_texture_downloader_set_texture (GdkTextureDownloader *self,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (GDK_IS_TEXTURE (texture));
|
||||
|
||||
g_set_object (&self->texture, texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_get_texture:
|
||||
* @self: a texture downloader
|
||||
*
|
||||
* Gets the texture that the downloader will download.
|
||||
*
|
||||
* Returns: (transfer none): The texture to download
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
GdkTexture *
|
||||
gdk_texture_downloader_get_texture (const GdkTextureDownloader *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
|
||||
return self->texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_set_format:
|
||||
* @self: a texture downloader
|
||||
* @format: the format to use
|
||||
*
|
||||
* Sets the format the downloader will download.
|
||||
*
|
||||
* By default, GDK_MEMORY_DEFAULT is set.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
void
|
||||
gdk_texture_downloader_set_format (GdkTextureDownloader *self,
|
||||
GdkMemoryFormat format)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
self->format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_get_format:
|
||||
* @self: a texture downloader
|
||||
*
|
||||
* Gets the format that the data will be downloaded in.
|
||||
*
|
||||
* Returns: The format of the download
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
GdkMemoryFormat
|
||||
gdk_texture_downloader_get_format (const GdkTextureDownloader *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, GDK_MEMORY_DEFAULT);
|
||||
|
||||
return self->format;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_download_into:
|
||||
* @self: a texture downloader
|
||||
* @data: (array): pointer to enough memory to be filled with the
|
||||
* downloaded data of the texture
|
||||
* @stride: rowstride in bytes
|
||||
*
|
||||
* Downloads the @texture into local memory.
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
void
|
||||
gdk_texture_downloader_download_into (const GdkTextureDownloader *self,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (stride >= gdk_texture_get_width (self->texture) * gdk_memory_format_bytes_per_pixel (self->format));
|
||||
|
||||
gdk_texture_do_download (self->texture, self->format, data, stride);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_downloader_download_bytes:
|
||||
* @self: the downloader
|
||||
* @out_stride: (out): The stride of the resulting data in bytes.
|
||||
*
|
||||
* Downloads the given texture pixels into a `GBytes`. The rowstride will
|
||||
* be stored in the stride value.
|
||||
*
|
||||
* This function will abort if it tries to download a large texture and
|
||||
* fails to allocate memory. If you think that may happen, you should
|
||||
* handle memory allocation yourself and use
|
||||
* gdk_texture_downloader_download_into() once allocation succeeded.
|
||||
*
|
||||
* Returns: The downloaded pixels.
|
||||
*
|
||||
* Since: 4.10
|
||||
**/
|
||||
GBytes *
|
||||
gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self,
|
||||
gsize *out_stride)
|
||||
{
|
||||
guchar *data;
|
||||
gsize stride;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
g_return_val_if_fail (out_stride != NULL, NULL);
|
||||
|
||||
if (GDK_IS_MEMORY_TEXTURE (self->texture) &&
|
||||
gdk_texture_get_format (self->texture) == self->format)
|
||||
{
|
||||
GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (self->texture);
|
||||
|
||||
return g_bytes_ref (gdk_memory_texture_get_bytes (memtex, out_stride));
|
||||
}
|
||||
|
||||
stride = self->texture->width * gdk_memory_format_bytes_per_pixel (self->format);
|
||||
data = g_malloc_n (stride, self->texture->height);
|
||||
|
||||
gdk_texture_do_download (self->texture, self->format, data, stride);
|
||||
|
||||
*out_stride = stride;
|
||||
return g_bytes_new_take (data, stride * self->texture->height);
|
||||
}
|
||||
|
||||
69
gdk/gdktexturedownloader.h
Normal file
69
gdk/gdktexturedownloader.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2023 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_TEXTURE_DOWNLOADER_H__
|
||||
#define __GTK_TEXTURE_DOWNLOADER_H__
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdkenums.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_TEXTURE_DOWNLOADER (gdk_texture_downloader_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GType gdk_texture_downloader_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkTextureDownloader * gdk_texture_downloader_new (GdkTexture *texture);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkTextureDownloader * gdk_texture_downloader_copy (const GdkTextureDownloader *self);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gdk_texture_downloader_free (GdkTextureDownloader *self);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gdk_texture_downloader_set_texture (GdkTextureDownloader *self,
|
||||
GdkTexture *texture);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkTexture * gdk_texture_downloader_get_texture (const GdkTextureDownloader *self);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gdk_texture_downloader_set_format (GdkTextureDownloader *self,
|
||||
GdkMemoryFormat format);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GdkMemoryFormat gdk_texture_downloader_get_format (const GdkTextureDownloader *self);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gdk_texture_downloader_download_into (const GdkTextureDownloader *self,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GBytes * gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self,
|
||||
gsize *out_stride);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkTextureDownloader, gdk_texture_downloader_free)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TEXTURE_DOWNLOADER_H__ */
|
||||
41
gdk/gdktexturedownloaderprivate.h
Normal file
41
gdk/gdktexturedownloaderprivate.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
*
|
||||
* Copyright (C) 2023 Benjamin Otte
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__
|
||||
#define __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__
|
||||
|
||||
#include "gdktexturedownloader.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GdkTextureDownloader
|
||||
{
|
||||
/*< private >*/
|
||||
GdkTexture *texture;
|
||||
GdkMemoryFormat format;
|
||||
};
|
||||
|
||||
void gdk_texture_downloader_init (GdkTextureDownloader *self,
|
||||
GdkTexture *texture);
|
||||
void gdk_texture_downloader_finish (GdkTextureDownloader *self);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__ */
|
||||
@@ -43,7 +43,6 @@ void gdk_texture_do_download (GdkTexture
|
||||
GdkMemoryFormat format,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
GdkMemoryFormat gdk_texture_get_format (GdkTexture *self);
|
||||
gboolean gdk_texture_set_render_data (GdkTexture *self,
|
||||
gpointer key,
|
||||
gpointer data,
|
||||
|
||||
@@ -77,6 +77,7 @@ typedef struct _GdkContentFormats GdkContentFormats;
|
||||
typedef struct _GdkContentProvider GdkContentProvider;
|
||||
typedef struct _GdkCursor GdkCursor;
|
||||
typedef struct _GdkTexture GdkTexture;
|
||||
typedef struct _GdkTextureDownloader GdkTextureDownloader;
|
||||
typedef struct _GdkDevice GdkDevice;
|
||||
typedef struct _GdkDrag GdkDrag;
|
||||
typedef struct _GdkDrop GdkDrop;
|
||||
|
||||
@@ -128,6 +128,16 @@
|
||||
*/
|
||||
#define GDK_VERSION_4_10 (G_ENCODE_VERSION (4, 10))
|
||||
|
||||
/**
|
||||
* GDK_VERSION_4_12:
|
||||
*
|
||||
* A macro that evaluates to the 4.12 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*
|
||||
* Since: 4.12
|
||||
*/
|
||||
#define GDK_VERSION_4_12 (G_ENCODE_VERSION (4, 12))
|
||||
|
||||
|
||||
/* evaluates to the current stable version; for development cycles,
|
||||
* this means the next stable target, with a hard backstop to the
|
||||
@@ -297,4 +307,18 @@
|
||||
# define GDK_DEPRECATED_IN_4_10_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_12
|
||||
# define GDK_AVAILABLE_IN_4_12 GDK_UNAVAILABLE(4, 12)
|
||||
#else
|
||||
# define GDK_AVAILABLE_IN_4_12 _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_12
|
||||
# define GDK_DEPRECATED_IN_4_12 GDK_DEPRECATED
|
||||
# define GDK_DEPRECATED_IN_4_12_FOR(f) GDK_DEPRECATED_FOR(f)
|
||||
#else
|
||||
# define GDK_DEPRECATED_IN_4_12 _GDK_EXTERN
|
||||
# define GDK_DEPRECATED_IN_4_12_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#endif /* __GDK_VERSION_MACROS_H__ */
|
||||
|
||||
@@ -221,6 +221,20 @@ gdk_vulkan_strerror (VkResult result)
|
||||
#endif
|
||||
#if VK_HEADER_VERSION < 140
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 218
|
||||
case VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
|
||||
return "The requested VkImageUsageFlags are not supported. (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
|
||||
return "The requested video picture layout is not supported. (VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR:
|
||||
return "A video profile operation specified via VkVideoProfileInfoKHR::videoCodecOperation is not supported. (VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR:
|
||||
return "Format parameters in a requested VkVideoProfileInfoKHR chain are not supported. (VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR:
|
||||
return "Codec-specific parameters in a requested (VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR)";
|
||||
case VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
|
||||
return "The specified video Std header version is not supported. (VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR)";
|
||||
#endif
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
default:
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include "gdktexture.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktexturedownloaderprivate.h"
|
||||
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
@@ -251,7 +251,8 @@ gdk_save_jpeg (GdkTexture *texture)
|
||||
guchar *data = NULL;
|
||||
gulong size = 0;
|
||||
guchar *input = NULL;
|
||||
GdkMemoryTexture *memtex = NULL;
|
||||
GdkTextureDownloader downloader;
|
||||
GBytes *texbytes;
|
||||
const guchar *texdata;
|
||||
gsize texstride;
|
||||
guchar *row;
|
||||
@@ -270,7 +271,7 @@ gdk_save_jpeg (GdkTexture *texture)
|
||||
free (data);
|
||||
g_free (input);
|
||||
jpeg_destroy_compress (&info);
|
||||
g_clear_object (&memtex);
|
||||
g_clear_pointer (&texbytes, g_bytes_unref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -289,10 +290,11 @@ gdk_save_jpeg (GdkTexture *texture)
|
||||
|
||||
jpeg_mem_dest (&info, &data, &size);
|
||||
|
||||
memtex = gdk_memory_texture_from_texture (texture,
|
||||
GDK_MEMORY_R8G8B8);
|
||||
texdata = gdk_memory_texture_get_data (memtex);
|
||||
texstride = gdk_memory_texture_get_stride (memtex);
|
||||
gdk_texture_downloader_init (&downloader, texture);
|
||||
gdk_texture_downloader_set_format (&downloader, GDK_MEMORY_R8G8B8);
|
||||
texbytes = gdk_texture_downloader_download_bytes (&downloader, &texstride);
|
||||
gdk_texture_downloader_finish (&downloader);
|
||||
texdata = g_bytes_get_data (texbytes, NULL);
|
||||
|
||||
jpeg_start_compress (&info, TRUE);
|
||||
|
||||
@@ -304,7 +306,7 @@ gdk_save_jpeg (GdkTexture *texture)
|
||||
|
||||
jpeg_finish_compress (&info);
|
||||
|
||||
g_object_unref (memtex);
|
||||
g_bytes_unref (texbytes);
|
||||
g_free (input);
|
||||
jpeg_destroy_compress (&info);
|
||||
|
||||
|
||||
@@ -21,10 +21,9 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdkmemorytexture.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdktexture.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdktexturedownloaderprivate.h"
|
||||
#include "gsk/gl/fp16private.h"
|
||||
#include <png.h>
|
||||
#include <stdio.h>
|
||||
@@ -297,11 +296,12 @@ gdk_save_png (GdkTexture *texture)
|
||||
png_info *info;
|
||||
png_io io = { NULL, 0, 0 };
|
||||
int width, height;
|
||||
int y;
|
||||
GdkMemoryFormat format;
|
||||
GdkTextureDownloader downloader;
|
||||
GBytes *bytes;
|
||||
gsize stride;
|
||||
const guchar *data;
|
||||
int y;
|
||||
GdkMemoryTexture *memtex;
|
||||
GdkMemoryFormat format;
|
||||
int png_format;
|
||||
int depth;
|
||||
|
||||
@@ -370,11 +370,15 @@ gdk_save_png (GdkTexture *texture)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memtex = gdk_memory_texture_from_texture (texture, format);
|
||||
gdk_texture_downloader_init (&downloader, texture);
|
||||
gdk_texture_downloader_set_format (&downloader, format);
|
||||
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
|
||||
gdk_texture_downloader_finish (&downloader);
|
||||
data = g_bytes_get_data (bytes, NULL);
|
||||
|
||||
if (sigsetjmp (png_jmpbuf (png), 1))
|
||||
{
|
||||
g_object_unref (memtex);
|
||||
g_bytes_unref (bytes);
|
||||
g_free (io.data);
|
||||
png_destroy_read_struct (&png, &info, NULL);
|
||||
return NULL;
|
||||
@@ -394,8 +398,6 @@ gdk_save_png (GdkTexture *texture)
|
||||
png_set_swap (png);
|
||||
#endif
|
||||
|
||||
data = gdk_memory_texture_get_data (memtex);
|
||||
stride = gdk_memory_texture_get_stride (memtex);
|
||||
for (y = 0; y < height; y++)
|
||||
png_write_row (png, data + y * stride);
|
||||
|
||||
@@ -403,7 +405,7 @@ gdk_save_png (GdkTexture *texture)
|
||||
|
||||
png_destroy_write_struct (&png, &info);
|
||||
|
||||
g_object_unref (memtex);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return g_bytes_new_take (io.data, io.size);
|
||||
}
|
||||
|
||||
@@ -21,10 +21,9 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdkmemorytexture.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdktexture.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdktexturedownloaderprivate.h"
|
||||
|
||||
#include <tiffio.h>
|
||||
|
||||
@@ -260,11 +259,12 @@ GBytes *
|
||||
gdk_save_tiff (GdkTexture *texture)
|
||||
{
|
||||
TIFF *tif;
|
||||
int width, height, stride;
|
||||
int width, height;
|
||||
gsize stride;
|
||||
const guchar *line;
|
||||
const guchar *data;
|
||||
GBytes *result = NULL;
|
||||
GdkMemoryTexture *memtex;
|
||||
GBytes *bytes, *result = NULL;
|
||||
GdkTextureDownloader downloader;
|
||||
GdkMemoryFormat format;
|
||||
const FormatData *fdata = NULL;
|
||||
|
||||
@@ -292,9 +292,11 @@ gdk_save_tiff (GdkTexture *texture)
|
||||
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||
|
||||
memtex = gdk_memory_texture_from_texture (texture, fdata->format);
|
||||
data = gdk_memory_texture_get_data (memtex);
|
||||
stride = gdk_memory_texture_get_stride (memtex);
|
||||
gdk_texture_downloader_init (&downloader, texture);
|
||||
gdk_texture_downloader_set_format (&downloader, fdata->format);
|
||||
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
|
||||
gdk_texture_downloader_finish (&downloader);
|
||||
data = g_bytes_get_data (bytes, NULL);
|
||||
|
||||
line = (const guchar *)data;
|
||||
for (int y = 0; y < height; y++)
|
||||
@@ -302,7 +304,7 @@ gdk_save_tiff (GdkTexture *texture)
|
||||
if (TIFFWriteScanline (tif, (void *)line, y, 0) == -1)
|
||||
{
|
||||
TIFFClose (tif);
|
||||
g_object_unref (memtex);
|
||||
g_bytes_unref (bytes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -314,7 +316,7 @@ gdk_save_tiff (GdkTexture *texture)
|
||||
|
||||
g_assert (result);
|
||||
|
||||
g_object_unref (memtex);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ static void
|
||||
push_nsevent (GdkEvent *gdk_event,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkToNSEventMap *map = g_slice_new0 (GdkToNSEventMap);
|
||||
GdkToNSEventMap *map = g_new0 (GdkToNSEventMap, 1);
|
||||
|
||||
map->link.data = map;
|
||||
map->gdk_event = gdk_event_ref (gdk_event);
|
||||
@@ -297,7 +297,7 @@ push_nsevent (GdkEvent *gdk_event,
|
||||
|
||||
gdk_event_unref (map->gdk_event);
|
||||
[map->nsevent release];
|
||||
g_slice_free (GdkToNSEventMap, map);
|
||||
g_free (map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ gdk_macos_zoomback_destroy (GdkMacosZoomback *zb)
|
||||
{
|
||||
gdk_surface_hide (GDK_SURFACE (zb->drag->drag_surface));
|
||||
g_clear_object (&zb->drag);
|
||||
g_slice_free (GdkMacosZoomback, zb);
|
||||
g_free (zb);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -157,7 +157,7 @@ gdk_macos_drag_drop_done (GdkDrag *drag,
|
||||
/* Apple HIG suggests doing a "zoomback" animation of the surface back
|
||||
* towards the original position.
|
||||
*/
|
||||
zb = g_slice_new0 (GdkMacosZoomback);
|
||||
zb = g_new0 (GdkMacosZoomback, 1);
|
||||
zb->drag = g_object_ref (self);
|
||||
zb->frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self->drag_surface));
|
||||
zb->start_time = gdk_frame_clock_get_frame_time (zb->frame_clock);
|
||||
|
||||
@@ -423,7 +423,7 @@ write_request_free (WriteRequest *wr)
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_slice_free (WriteRequest, wr);
|
||||
g_free (wr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -491,7 +491,7 @@ on_data_ready_cb (GObject *object,
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr = g_new0 (WriteRequest, 1);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
|
||||
@@ -16,6 +16,8 @@ gdk_public_sources = files([
|
||||
'gdkdisplay.c',
|
||||
'gdkdisplaymanager.c',
|
||||
'gdkdrag.c',
|
||||
'gdkdragsurface.c',
|
||||
'gdkdragsurfacesize.c',
|
||||
'gdkdrawcontext.c',
|
||||
'gdkdrop.c',
|
||||
'gdkevents.c',
|
||||
@@ -43,6 +45,7 @@ gdk_public_sources = files([
|
||||
'gdkseatdefault.c',
|
||||
'gdksnapshot.c',
|
||||
'gdktexture.c',
|
||||
'gdktexturedownloader.c',
|
||||
'gdkvulkancontext.c',
|
||||
'gdksurface.c',
|
||||
'gdkpopuplayout.c',
|
||||
@@ -51,7 +54,6 @@ gdk_public_sources = files([
|
||||
'gdktoplevellayout.c',
|
||||
'gdktoplevelsize.c',
|
||||
'gdktoplevel.c',
|
||||
'gdkdragsurface.c',
|
||||
'loaders/gdkpng.c',
|
||||
'loaders/gdktiff.c',
|
||||
'loaders/gdkjpeg.c',
|
||||
@@ -75,6 +77,7 @@ gdk_public_headers = files([
|
||||
'gdkdisplay.h',
|
||||
'gdkdisplaymanager.h',
|
||||
'gdkdrag.h',
|
||||
'gdkdragsurfacesize.h',
|
||||
'gdkdrawcontext.h',
|
||||
'gdkdrop.h',
|
||||
'gdkenums.h',
|
||||
@@ -95,6 +98,7 @@ gdk_public_headers = files([
|
||||
'gdkseat.h',
|
||||
'gdksnapshot.h',
|
||||
'gdktexture.h',
|
||||
'gdktexturedownloader.h',
|
||||
'gdktypes.h',
|
||||
'gdkvulkancontext.h',
|
||||
'gdksurface.h',
|
||||
@@ -129,7 +133,7 @@ gdk_gresource_xml = configure_file(output: 'gdk.gresource.xml',
|
||||
|
||||
gdkresources = gnome.compile_resources('gdkresources',
|
||||
gdk_gresource_xml,
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
c_name: '_gdk',
|
||||
extra_args: '--manual-register',
|
||||
)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
@@ -78,6 +79,17 @@ gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
|
||||
|
||||
if (impl->next_layout.surface_geometry_dirty)
|
||||
{
|
||||
GdkDragSurfaceSize size;
|
||||
|
||||
gdk_drag_surface_size_init (&size);
|
||||
size.width = impl->next_layout.configured_width;
|
||||
size.height = impl->next_layout.configured_height;
|
||||
|
||||
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
|
||||
|
||||
impl->next_layout.configured_width = size.width;
|
||||
impl->next_layout.configured_height = size.height;
|
||||
|
||||
gdk_wayland_surface_update_size (surface,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdksurface-wayland.h"
|
||||
#include "gdksurface-wayland-private.h"
|
||||
|
||||
#include "gdkwaylanddisplay.h"
|
||||
#include "gdkwaylandglcontext.h"
|
||||
@@ -60,10 +61,20 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
int dx = impl->pending_buffer_offset_x;
|
||||
int dy = impl->pending_buffer_offset_y;
|
||||
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
if (wl_surface_get_version (impl->display_server.wl_surface) >=
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
@@ -110,7 +121,7 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||
{
|
||||
GdkWaylandDisplay *self = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
if (!gdk_display_init_egl (display,
|
||||
if (!gdk_display_init_egl (display,
|
||||
EGL_PLATFORM_WAYLAND_EXT,
|
||||
self->wl_display,
|
||||
TRUE,
|
||||
|
||||
@@ -229,7 +229,7 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
|
||||
if (impl->display_server.egl_window)
|
||||
wl_egl_window_resize (impl->display_server.egl_window, width * scale, height * scale, 0, 0);
|
||||
if (impl->display_server.wl_surface)
|
||||
if (impl->display_server.wl_surface && scale_changed)
|
||||
wl_surface_set_buffer_scale (impl->display_server.wl_surface, scale);
|
||||
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
@@ -561,8 +561,14 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
|
||||
/* Attach this new buffer to the surface */
|
||||
wl_surface_attach (impl->display_server.wl_surface,
|
||||
_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface),
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
0, 0);
|
||||
|
||||
if ((impl->pending_buffer_offset_x || impl->pending_buffer_offset_y) &&
|
||||
wl_surface_get_version (impl->display_server.wl_surface) >=
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
wl_surface_offset (impl->display_server.wl_surface,
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
|
||||
@@ -579,33 +585,12 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_sync_offset (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (wl_surface_get_version (impl->display_server.wl_surface) <
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
return;
|
||||
|
||||
if (impl->pending_buffer_offset_x == 0 &&
|
||||
impl->pending_buffer_offset_y == 0)
|
||||
return;
|
||||
|
||||
wl_surface_offset (impl->display_server.wl_surface,
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_surface_sync (GdkSurface *surface)
|
||||
{
|
||||
gdk_wayland_surface_sync_shadow (surface);
|
||||
gdk_wayland_surface_sync_opaque_region (surface);
|
||||
gdk_wayland_surface_sync_input_region (surface);
|
||||
gdk_wayland_surface_sync_offset (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -992,6 +977,15 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
impl->display_server.egl_window = NULL;
|
||||
}
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
if (impl->display_server.xdg_surface)
|
||||
{
|
||||
xdg_surface_destroy (impl->display_server.xdg_surface);
|
||||
@@ -1010,15 +1004,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
impl->initial_configure_received = FALSE;
|
||||
}
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
|
||||
|
||||
g_slist_free (impl->display_server.outputs);
|
||||
|
||||
@@ -1005,7 +1005,8 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
} bmi;
|
||||
HDC hdc;
|
||||
uint8_t *pixels, *bits;
|
||||
int rowstride, x, y, w, h;
|
||||
int x, y, w, h;
|
||||
gsize rowstride;
|
||||
|
||||
if (!GDI_CALL (GetIconInfo, (hicon, &ii)))
|
||||
return NULL;
|
||||
@@ -1057,7 +1058,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
no_alpha = FALSE;
|
||||
pixels += 4;
|
||||
}
|
||||
pixels += (w * 4 - rowstride);
|
||||
pixels += rowstride - w * 4;
|
||||
}
|
||||
|
||||
/* mask */
|
||||
@@ -1072,7 +1073,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
pixels[3] = 255 - bits[(x + y * w) * 4];
|
||||
pixels += 4;
|
||||
}
|
||||
pixels += (w * 4 - rowstride);
|
||||
pixels += rowstride - w * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1146,7 +1147,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
||||
xorp++;
|
||||
}
|
||||
}
|
||||
pixels += (w * 4 - rowstride);
|
||||
pixels += rowstride - w * 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1836,7 +1836,7 @@ static void
|
||||
gdk_drag_anim_destroy (GdkDragAnim *anim)
|
||||
{
|
||||
g_object_unref (anim->drag);
|
||||
g_slice_free (GdkDragAnim, anim);
|
||||
g_free (anim);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1936,7 +1936,7 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
|
||||
cairo_surface_destroy (surface);
|
||||
*/
|
||||
|
||||
anim = g_slice_new0 (GdkDragAnim);
|
||||
anim = g_new0 (GdkDragAnim, 1);
|
||||
g_set_object (&anim->drag, drag_win32);
|
||||
anim->frame_clock = gdk_surface_get_frame_clock (drag_win32->drag_surface);
|
||||
anim->start_time = gdk_frame_clock_get_frame_time (anim->frame_clock);
|
||||
|
||||
@@ -1975,7 +1975,7 @@ gdk_x11_display_finalize (GObject *object)
|
||||
if (trap->end_sequence == 0)
|
||||
g_warning ("Display finalized with an unpopped error trap");
|
||||
|
||||
g_slice_free (GdkErrorTrap, trap);
|
||||
g_free (trap);
|
||||
}
|
||||
|
||||
g_free (display_x11->program_class);
|
||||
@@ -2499,7 +2499,7 @@ delete_outdated_error_traps (GdkX11Display *display_x11)
|
||||
tmp_list = tmp_list->next;
|
||||
display_x11->error_traps =
|
||||
g_slist_delete_link (display_x11->error_traps, free_me);
|
||||
g_slice_free (GdkErrorTrap, trap);
|
||||
g_free (trap);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2531,7 +2531,7 @@ gdk_x11_display_error_trap_push (GdkDisplay *display)
|
||||
/* set up the Xlib callback to tell us about errors */
|
||||
_gdk_x11_error_handler_push ();
|
||||
|
||||
trap = g_slice_new0 (GdkErrorTrap);
|
||||
trap = g_new0 (GdkErrorTrap, 1);
|
||||
|
||||
trap->start_sequence = XNextRequest (display_x11->xdisplay);
|
||||
trap->error_code = Success;
|
||||
|
||||
@@ -1783,7 +1783,7 @@ gdk_drag_anim_destroy (GdkDragAnim *anim)
|
||||
{
|
||||
gdk_surface_hide (anim->drag->drag_surface);
|
||||
g_object_unref (anim->drag);
|
||||
g_slice_free (GdkDragAnim, anim);
|
||||
g_free (anim);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1882,7 +1882,7 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
|
||||
cairo_surface_destroy (surface);
|
||||
*/
|
||||
|
||||
anim = g_slice_new0 (GdkDragAnim);
|
||||
anim = g_new0 (GdkDragAnim, 1);
|
||||
anim->drag = g_object_ref (x11_drag);
|
||||
anim->frame_clock = gdk_surface_get_frame_clock (x11_drag->drag_surface);
|
||||
anim->start_time = gdk_frame_clock_get_frame_time (anim->frame_clock);
|
||||
@@ -1912,7 +1912,7 @@ drag_grab (GdkDrag *drag)
|
||||
root = GDK_DISPLAY_XROOTWIN (display);
|
||||
seat = gdk_device_get_seat (gdk_drag_get_device (drag));
|
||||
|
||||
capabilities = GDK_SEAT_CAPABILITY_ALL_POINTING;
|
||||
capabilities = GDK_SEAT_CAPABILITY_ALL_POINTING | GDK_SEAT_CAPABILITY_KEYBOARD;
|
||||
|
||||
cursor = gdk_drag_get_cursor (drag, x11_drag->current_action);
|
||||
g_set_object (&x11_drag->cursor, cursor);
|
||||
|
||||
@@ -79,7 +79,7 @@ gdk_x11_pending_selection_notify_new (Window window,
|
||||
{
|
||||
GdkX11PendingSelectionNotify *pending;
|
||||
|
||||
pending = g_slice_new0 (GdkX11PendingSelectionNotify);
|
||||
pending = g_new0 (GdkX11PendingSelectionNotify, 1);
|
||||
pending->n_pending = 1;
|
||||
|
||||
pending->xevent.type = SelectionNotify;
|
||||
@@ -97,7 +97,7 @@ gdk_x11_pending_selection_notify_new (Window window,
|
||||
static void
|
||||
gdk_x11_pending_selection_notify_free (GdkX11PendingSelectionNotify *notify)
|
||||
{
|
||||
g_slice_free (GdkX11PendingSelectionNotify, notify);
|
||||
g_free (notify);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -731,7 +731,7 @@ handle_timestamp_done (GObject *stream,
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_slice_free (gulong, user_data);
|
||||
g_free (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -747,7 +747,7 @@ handle_timestamp (GOutputStream *stream,
|
||||
{
|
||||
gulong *time_;
|
||||
|
||||
time_ = g_slice_new (gulong);
|
||||
time_ = g_new (gulong, 1);
|
||||
*time_ = timestamp;
|
||||
|
||||
g_output_stream_write_all_async (stream,
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "gdkglcontext-x11.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
#include "gdkprivate.h"
|
||||
@@ -345,6 +346,36 @@ compute_toplevel_size (GdkSurface *surface,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compute_drag_surface_size (GdkSurface *surface,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
|
||||
GdkDragSurfaceSize size;
|
||||
|
||||
gdk_drag_surface_size_init (&size);
|
||||
size.width = impl->next_layout.configured_width;
|
||||
size.height = impl->next_layout.configured_height;
|
||||
|
||||
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
|
||||
|
||||
if ((impl->last_computed_width != size.width ||
|
||||
impl->last_computed_height != size.height) &&
|
||||
(impl->next_layout.configured_width != size.width ||
|
||||
impl->next_layout.configured_height != size.height))
|
||||
{
|
||||
*width = size.width;
|
||||
*height = size.height;
|
||||
impl->last_computed_width = size.width;
|
||||
impl->last_computed_height = size.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compute_size_idle (gpointer user_data)
|
||||
{
|
||||
@@ -394,6 +425,24 @@ gdk_x11_surface_compute_size (GdkSurface *surface)
|
||||
impl->surface_scale);
|
||||
}
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
impl->next_layout.configure_pending = FALSE;
|
||||
}
|
||||
else if (GDK_IS_DRAG_SURFACE (surface))
|
||||
{
|
||||
int width, height;
|
||||
|
||||
if (compute_drag_surface_size (surface, &width, &height))
|
||||
gdk_x11_surface_toplevel_resize (surface, width, height);
|
||||
|
||||
if (surface->resize_count == 0)
|
||||
{
|
||||
gdk_x11_surface_update_size (impl,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
impl->surface_scale);
|
||||
}
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
impl->next_layout.configure_pending = FALSE;
|
||||
}
|
||||
@@ -787,7 +836,7 @@ free_pixmap (gpointer datap)
|
||||
}
|
||||
|
||||
g_object_unref (data->display);
|
||||
g_slice_free (FreePixmapData, data);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -798,7 +847,7 @@ attach_free_pixmap_handler (cairo_surface_t *surface,
|
||||
static const cairo_user_data_key_t key;
|
||||
FreePixmapData *data;
|
||||
|
||||
data = g_slice_new (FreePixmapData);
|
||||
data = g_new (FreePixmapData, 1);
|
||||
data->display = g_object_ref (display);
|
||||
data->pixmap = pixmap;
|
||||
|
||||
@@ -1358,6 +1407,7 @@ gdk_x11_surface_destroy (GdkSurface *surface,
|
||||
|
||||
unhook_surface_changed (surface);
|
||||
disconnect_frame_clock (surface);
|
||||
g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
|
||||
|
||||
if (impl->cairo_surface)
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ gsk_gl_attachment_state_new (void)
|
||||
self->textures[i].id = 0;
|
||||
self->textures[i].changed = FALSE;
|
||||
self->textures[i].initial = TRUE;
|
||||
self->textures[i].sampler = sampler_index (GL_LINEAR, GL_LINEAR);
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -65,9 +66,12 @@ void
|
||||
gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||
GLenum target,
|
||||
GLenum texture,
|
||||
guint id)
|
||||
guint id,
|
||||
GLint min_filter,
|
||||
GLint mag_filter)
|
||||
{
|
||||
GskGLBindTexture *attach;
|
||||
unsigned int sampler;
|
||||
|
||||
g_assert (self != NULL);
|
||||
g_assert (target == GL_TEXTURE_1D ||
|
||||
@@ -77,12 +81,16 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||
|
||||
attach = &self->textures[texture - GL_TEXTURE0];
|
||||
|
||||
if (attach->target != target || attach->texture != texture || attach->id != id)
|
||||
sampler = sampler_index (min_filter, mag_filter);
|
||||
|
||||
if (attach->target != target || attach->texture != texture || attach->id != id ||
|
||||
attach->sampler != sampler)
|
||||
{
|
||||
attach->target = target;
|
||||
attach->texture = texture;
|
||||
attach->id = id;
|
||||
attach->initial = FALSE;
|
||||
attach->sampler = sampler;
|
||||
|
||||
if (attach->changed == FALSE)
|
||||
{
|
||||
|
||||
@@ -29,11 +29,37 @@ typedef struct _GskGLAttachmentState GskGLAttachmentState;
|
||||
typedef struct _GskGLBindFramebuffer GskGLBindFramebuffer;
|
||||
typedef struct _GskGLBindTexture GskGLBindTexture;
|
||||
|
||||
#define GSK_GL_N_FILTERS 3
|
||||
|
||||
static inline guint
|
||||
filter_index (GLint filter)
|
||||
{
|
||||
switch (filter)
|
||||
{
|
||||
case GL_LINEAR:
|
||||
return 0;
|
||||
case GL_NEAREST:
|
||||
return 1;
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
return 2;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static inline guint
|
||||
sampler_index (GLint min_filter,
|
||||
GLint mag_filter)
|
||||
{
|
||||
return filter_index (min_filter) * GSK_GL_N_FILTERS + filter_index (mag_filter);
|
||||
}
|
||||
|
||||
struct _GskGLBindTexture
|
||||
{
|
||||
guint changed : 1;
|
||||
guint initial : 1;
|
||||
GLenum target : 30;
|
||||
GLenum target : 26;
|
||||
guint sampler : 4;
|
||||
GLenum texture;
|
||||
guint id;
|
||||
};
|
||||
@@ -62,7 +88,9 @@ void gsk_gl_attachment_state_unref (GskGLAttachmentS
|
||||
void gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||
GLenum target,
|
||||
GLenum texture,
|
||||
guint id);
|
||||
guint id,
|
||||
GLint min_filter,
|
||||
GLint mag_filter);
|
||||
void gsk_gl_attachment_state_bind_framebuffer (GskGLAttachmentState *self,
|
||||
guint id);
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdkmemoryformatprivate.h>
|
||||
#include <gdk/gdkmemorytextureprivate.h>
|
||||
#include <gdk/gdkprofilerprivate.h>
|
||||
#include <gdk/gdktexturedownloaderprivate.h>
|
||||
#include <gsk/gskdebugprivate.h>
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
|
||||
@@ -247,6 +247,16 @@ will_ignore_batch (GskGLCommandQueue *self)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline GLint
|
||||
filter_from_index (guint index)
|
||||
{
|
||||
GLint filters[3] = { GL_LINEAR, GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR };
|
||||
|
||||
g_assert (index < GSK_GL_N_FILTERS);
|
||||
|
||||
return filters[index];
|
||||
}
|
||||
|
||||
static inline guint
|
||||
snapshot_attachments (const GskGLAttachmentState *state,
|
||||
GskGLCommandBinds *array)
|
||||
@@ -260,6 +270,7 @@ snapshot_attachments (const GskGLAttachmentState *state,
|
||||
{
|
||||
bind[count].id = state->textures[i].id;
|
||||
bind[count].texture = state->textures[i].texture;
|
||||
bind[count].sampler = state->textures[i].sampler;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -400,10 +411,12 @@ gsk_gl_command_queue_dispose (GObject *object)
|
||||
g_clear_pointer (&self->attachments, gsk_gl_attachment_state_unref);
|
||||
g_clear_pointer (&self->uniforms, gsk_gl_uniform_state_unref);
|
||||
|
||||
if (self->has_samplers)
|
||||
glDeleteSamplers (G_N_ELEMENTS (self->samplers), self->samplers);
|
||||
|
||||
gsk_gl_command_batches_clear (&self->batches);
|
||||
gsk_gl_command_binds_clear (&self->batch_binds);
|
||||
gsk_gl_command_uniforms_clear (&self->batch_uniforms);
|
||||
gsk_gl_syncs_clear (&self->syncs);
|
||||
|
||||
gsk_gl_buffer_destroy (&self->vertices);
|
||||
|
||||
@@ -426,7 +439,6 @@ gsk_gl_command_queue_init (GskGLCommandQueue *self)
|
||||
gsk_gl_command_batches_init (&self->batches, 128);
|
||||
gsk_gl_command_binds_init (&self->batch_binds, 1024);
|
||||
gsk_gl_command_uniforms_init (&self->batch_uniforms, 2048);
|
||||
gsk_gl_syncs_init (&self->syncs, 10);
|
||||
|
||||
gsk_gl_buffer_init (&self->vertices, GL_ARRAY_BUFFER, sizeof (GskGLDrawVertex));
|
||||
}
|
||||
@@ -436,6 +448,7 @@ gsk_gl_command_queue_new (GdkGLContext *context,
|
||||
GskGLUniformState *uniforms)
|
||||
{
|
||||
GskGLCommandQueue *self;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
||||
|
||||
@@ -451,7 +464,37 @@ gsk_gl_command_queue_new (GdkGLContext *context,
|
||||
|
||||
/* Determine max texture size immediately and restore context */
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &self->max_texture_size);
|
||||
if (g_getenv ("GSK_MAX_TEXTURE_SIZE"))
|
||||
{
|
||||
int max_texture_size = atoi (g_getenv ("GSK_MAX_TEXTURE_SIZE"));
|
||||
if (max_texture_size == 0)
|
||||
{
|
||||
g_warning ("Failed to parse GSK_MAX_TEXTURE_SIZE");
|
||||
}
|
||||
else
|
||||
{
|
||||
max_texture_size = MAX (max_texture_size, 512);
|
||||
GSK_DEBUG(OPENGL, "Limiting max texture size to %d", max_texture_size);
|
||||
self->max_texture_size = MIN (self->max_texture_size, max_texture_size);
|
||||
}
|
||||
}
|
||||
|
||||
self->has_samplers = gdk_gl_context_check_version (context, 3, 3, 3, 0);
|
||||
|
||||
/* create the samplers */
|
||||
if (self->has_samplers)
|
||||
{
|
||||
glGenSamplers (G_N_ELEMENTS (self->samplers), self->samplers);
|
||||
for (i = 0; i < G_N_ELEMENTS (self->samplers); i++)
|
||||
{
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_MIN_FILTER, filter_from_index(i / GSK_GL_N_FILTERS));
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_MAG_FILTER, filter_from_index(i % GSK_GL_N_FILTERS));
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri (self->samplers[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
@@ -974,6 +1017,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
guint vao_id;
|
||||
guint vbo_id;
|
||||
int textures[4];
|
||||
int samplers[4];
|
||||
int framebuffer = -1;
|
||||
int next_batch_index;
|
||||
int active = -1;
|
||||
@@ -986,6 +1030,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (textures); i++)
|
||||
textures[i] = -1;
|
||||
for (guint i = 0; i < G_N_ELEMENTS (samplers); i++)
|
||||
samplers[i] = -1;
|
||||
|
||||
gsk_gl_command_queue_sort_batches (self);
|
||||
|
||||
@@ -1100,27 +1146,36 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
if G_UNLIKELY (batch->draw.bind_count > 0)
|
||||
{
|
||||
const GskGLCommandBind *bind = &self->batch_binds.items[batch->draw.bind_offset];
|
||||
|
||||
for (guint i = 0; i < batch->draw.bind_count; i++)
|
||||
{
|
||||
if (textures[bind->texture] != bind->id)
|
||||
{
|
||||
GskGLSync *s;
|
||||
|
||||
if (active != bind->texture)
|
||||
{
|
||||
active = bind->texture;
|
||||
glActiveTexture (GL_TEXTURE0 + bind->texture);
|
||||
}
|
||||
|
||||
s = gsk_gl_syncs_get_sync (&self->syncs, bind->id);
|
||||
if (s && s->sync)
|
||||
{
|
||||
glWaitSync ((GLsync) s->sync, 0, GL_TIMEOUT_IGNORED);
|
||||
s->sync = NULL;
|
||||
}
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, bind->id);
|
||||
textures[bind->texture] = bind->id;
|
||||
if (!self->has_samplers)
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_from_index(bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_from_index(bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
}
|
||||
|
||||
if (samplers[bind->texture] != bind->sampler)
|
||||
{
|
||||
if (self->has_samplers)
|
||||
glBindSampler (bind->texture, self->samplers[bind->sampler]);
|
||||
else
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_from_index(bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_from_index(bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
samplers[bind->texture] = bind->sampler;
|
||||
}
|
||||
|
||||
bind++;
|
||||
@@ -1246,7 +1301,6 @@ gsk_gl_command_queue_end_frame (GskGLCommandQueue *self)
|
||||
self->batches.len = 0;
|
||||
self->batch_binds.len = 0;
|
||||
self->batch_uniforms.len = 0;
|
||||
self->syncs.len = 0;
|
||||
self->n_uploads = 0;
|
||||
self->tail_batch_index = -1;
|
||||
self->in_frame = FALSE;
|
||||
@@ -1257,8 +1311,6 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
guint *out_fbo_id,
|
||||
guint *out_texture_id)
|
||||
{
|
||||
@@ -1272,9 +1324,8 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||
g_assert (out_texture_id != NULL);
|
||||
|
||||
texture_id = gsk_gl_command_queue_create_texture (self,
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter);
|
||||
width, height,
|
||||
format);
|
||||
|
||||
if (texture_id == -1)
|
||||
{
|
||||
@@ -1299,9 +1350,7 @@ int
|
||||
gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
int format)
|
||||
{
|
||||
GLuint texture_id = 0;
|
||||
|
||||
@@ -1317,9 +1366,9 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
@@ -1370,7 +1419,8 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
|
||||
GdkGLContext *context;
|
||||
const guchar *data;
|
||||
gsize stride;
|
||||
GdkMemoryTexture *memtex;
|
||||
GBytes *bytes;
|
||||
GdkTextureDownloader downloader;
|
||||
GdkMemoryFormat data_format;
|
||||
int width, height;
|
||||
GLenum gl_internalformat;
|
||||
@@ -1405,9 +1455,11 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
|
||||
}
|
||||
}
|
||||
|
||||
memtex = gdk_memory_texture_from_texture (texture, data_format);
|
||||
data = gdk_memory_texture_get_data (memtex);
|
||||
stride = gdk_memory_texture_get_stride (memtex);
|
||||
gdk_texture_downloader_init (&downloader, texture);
|
||||
gdk_texture_downloader_set_format (&downloader, data_format);
|
||||
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
|
||||
gdk_texture_downloader_finish (&downloader);
|
||||
data = g_bytes_get_data (bytes, NULL);
|
||||
bpp = gdk_memory_format_bytes_per_pixel (data_format);
|
||||
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format));
|
||||
@@ -1437,14 +1489,12 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
|
||||
}
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
|
||||
|
||||
g_object_unref (memtex);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
int
|
||||
gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
GdkTexture *texture)
|
||||
{
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
cairo_surface_t *surface = NULL;
|
||||
@@ -1453,7 +1503,6 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
|
||||
g_assert (!GDK_IS_GL_TEXTURE (texture));
|
||||
g_assert (mag_filter == GL_LINEAR || mag_filter == GL_NEAREST);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
@@ -1462,10 +1511,10 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
g_warning ("Attempt to create texture of size %ux%u but max size is %d. "
|
||||
"Clipping will occur.",
|
||||
width, height, self->max_texture_size);
|
||||
width = MAX (width, self->max_texture_size);
|
||||
height = MAX (height, self->max_texture_size);
|
||||
width = MIN (width, self->max_texture_size);
|
||||
height = MIN (height, self->max_texture_size);
|
||||
}
|
||||
texture_id = gsk_gl_command_queue_create_texture (self, width, height, GL_RGBA8, min_filter, mag_filter);
|
||||
texture_id = gsk_gl_command_queue_create_texture (self, width, height, GL_RGBA8);
|
||||
if (texture_id == -1)
|
||||
return texture_id;
|
||||
|
||||
@@ -1477,9 +1526,6 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
gsk_gl_command_queue_do_upload_texture (self, texture);
|
||||
|
||||
if (min_filter == GL_LINEAR_MIPMAP_LINEAR)
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
|
||||
/* Restore previous texture state if any */
|
||||
if (self->attachments->textures[0].id > 0)
|
||||
glBindTexture (self->attachments->textures[0].target,
|
||||
|
||||
@@ -53,10 +53,12 @@ typedef struct _GskGLCommandBind
|
||||
* texture will be placed into. We always use GL_TEXTURE_2D so we don't
|
||||
* waste any bits here to indicate that.
|
||||
*/
|
||||
guint texture : 5;
|
||||
guint texture : 4;
|
||||
|
||||
guint sampler : 4;
|
||||
|
||||
/* The identifier for the texture created with glGenTextures(). */
|
||||
guint id : 27;
|
||||
guint id: 24;
|
||||
} GskGLCommandBind;
|
||||
|
||||
G_STATIC_ASSERT (sizeof (GskGLCommandBind) == 4);
|
||||
@@ -167,15 +169,9 @@ typedef union _GskGLCommandBatch
|
||||
|
||||
G_STATIC_ASSERT (sizeof (GskGLCommandBatch) == 32);
|
||||
|
||||
typedef struct _GskGLSync {
|
||||
guint id;
|
||||
gpointer sync;
|
||||
} GskGLSync;
|
||||
|
||||
DEFINE_INLINE_ARRAY (GskGLCommandBatches, gsk_gl_command_batches, GskGLCommandBatch)
|
||||
DEFINE_INLINE_ARRAY (GskGLCommandBinds, gsk_gl_command_binds, GskGLCommandBind)
|
||||
DEFINE_INLINE_ARRAY (GskGLCommandUniforms, gsk_gl_command_uniforms, GskGLCommandUniform)
|
||||
DEFINE_INLINE_ARRAY (GskGLSyncs, gsk_gl_syncs, GskGLSync)
|
||||
|
||||
struct _GskGLCommandQueue
|
||||
{
|
||||
@@ -231,7 +227,12 @@ struct _GskGLCommandQueue
|
||||
*/
|
||||
GskGLCommandUniforms batch_uniforms;
|
||||
|
||||
GskGLSyncs syncs;
|
||||
/* Array of samplers that we use for mag/min filter handling. It is indexed
|
||||
* by the sampler_index() function.
|
||||
* Note that when samplers are not supported (hello GLES), we fall back to
|
||||
* setting the texture filter, but that needs to be done for every texture.
|
||||
*/
|
||||
GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];
|
||||
|
||||
/* Discovered max texture size when loading the command queue so that we
|
||||
* can either scale down or slice textures to fit within this size. Assumed
|
||||
@@ -265,6 +266,9 @@ struct _GskGLCommandQueue
|
||||
/* Counter for uploads on the frame */
|
||||
guint n_uploads;
|
||||
|
||||
/* If the GL context is new enough for sampler support */
|
||||
guint has_samplers : 1;
|
||||
|
||||
/* If we're inside a begin/end_frame pair */
|
||||
guint in_frame : 1;
|
||||
|
||||
@@ -289,22 +293,16 @@ void gsk_gl_command_queue_execute (GskGLCommandQueue
|
||||
const cairo_region_t *scissor,
|
||||
guint default_framebuffer);
|
||||
int gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
GdkTexture *texture);
|
||||
int gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
int format);
|
||||
guint gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self);
|
||||
gboolean gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
guint *out_fbo_id,
|
||||
guint *out_texture_id);
|
||||
void gsk_gl_command_queue_delete_program (GskGLCommandQueue *self,
|
||||
@@ -362,37 +360,6 @@ gsk_gl_command_queue_bind_framebuffer (GskGLCommandQueue *self,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline GskGLSync *
|
||||
gsk_gl_syncs_get_sync (GskGLSyncs *syncs,
|
||||
guint id)
|
||||
{
|
||||
for (unsigned int i = 0; i < syncs->len; i++)
|
||||
{
|
||||
GskGLSync *sync = &syncs->items[i];
|
||||
if (sync->id == id)
|
||||
return sync;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_syncs_add_sync (GskGLSyncs *syncs,
|
||||
guint id,
|
||||
gpointer sync)
|
||||
{
|
||||
GskGLSync *s;
|
||||
|
||||
s = gsk_gl_syncs_get_sync (syncs, id);
|
||||
if (s)
|
||||
g_assert (s->sync == sync);
|
||||
else
|
||||
{
|
||||
s = gsk_gl_syncs_append (syncs);
|
||||
s->id = id;
|
||||
s->sync = sync;
|
||||
}
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_GL_COMMAND_QUEUE_PRIVATE_H__ */
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "gskgliconlibraryprivate.h"
|
||||
#include "gskglprogramprivate.h"
|
||||
#include "gskglshadowlibraryprivate.h"
|
||||
#include "gskgltextureprivate.h"
|
||||
#include "fp16private.h"
|
||||
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
@@ -60,8 +59,7 @@ texture_key_hash (gconstpointer v)
|
||||
|
||||
return GPOINTER_TO_SIZE (k->pointer) ^
|
||||
((scale_x << 8) |
|
||||
(scale_y << 6) |
|
||||
(k->filter << 1) |
|
||||
(scale_y << 4) |
|
||||
k->pointer_is_child);
|
||||
}
|
||||
|
||||
@@ -75,7 +73,6 @@ texture_key_equal (gconstpointer v1,
|
||||
return k1->pointer == k2->pointer &&
|
||||
k1->scale_x == k2->scale_x &&
|
||||
k1->scale_y == k2->scale_y &&
|
||||
k1->filter == k2->filter &&
|
||||
k1->pointer_is_child == k2->pointer_is_child &&
|
||||
(!k1->pointer_is_child || memcmp (&k1->parent_rect, &k2->parent_rect, sizeof k1->parent_rect) == 0);
|
||||
}
|
||||
@@ -620,7 +617,7 @@ gsk_gl_driver_after_frame (GskGLDriver *self)
|
||||
|
||||
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
|
||||
gsk_gl_driver_autorelease_texture (self, render_target->texture_id);
|
||||
g_slice_free (GskGLRenderTarget, render_target);
|
||||
g_free (render_target);
|
||||
|
||||
self->render_targets->len--;
|
||||
}
|
||||
@@ -693,8 +690,7 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
|
||||
* gsk_gl_driver_load_texture:
|
||||
* @self: a `GdkTexture`
|
||||
* @texture: a `GdkTexture`
|
||||
* @min_filter: GL_NEAREST or GL_LINEAR
|
||||
* @mag_filter: GL_NEAREST or GL_LINEAR
|
||||
* @ensure_mipmap: Mipmaps for this texture must exist for downscaling
|
||||
*
|
||||
* Loads a `GdkTexture` by uploading the contents to the GPU when
|
||||
* necessary. If @texture is a `GdkGLTexture`, it can be used without
|
||||
@@ -715,8 +711,7 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
|
||||
guint
|
||||
gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
gboolean ensure_mipmap)
|
||||
{
|
||||
GdkGLContext *context;
|
||||
GdkMemoryTexture *downloaded_texture;
|
||||
@@ -724,7 +719,6 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
guint texture_id;
|
||||
int height;
|
||||
int width;
|
||||
int format;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), 0);
|
||||
@@ -732,9 +726,23 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
|
||||
context = self->command_queue->context;
|
||||
|
||||
format = GL_RGBA8;
|
||||
texture_id = 0;
|
||||
downloaded_texture = NULL;
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture))
|
||||
t = gdk_texture_get_render_data (texture, self);
|
||||
if (t && t->texture_id)
|
||||
{
|
||||
if (ensure_mipmap & !t->has_mipmap)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, t->texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
t->has_mipmap = TRUE;
|
||||
}
|
||||
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture) && !ensure_mipmap)
|
||||
{
|
||||
GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
|
||||
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
|
||||
@@ -744,36 +752,32 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
/* A GL texture from the same GL context is a simple task... */
|
||||
return gdk_gl_texture_get_id (gl_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (texture_id == 0)
|
||||
{
|
||||
if ((t = gdk_texture_get_render_data (texture, self)))
|
||||
{
|
||||
if (t->min_filter == min_filter && t->mag_filter == mag_filter && t->texture_id)
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
|
||||
}
|
||||
|
||||
/* The download_texture() call may have switched the GL context. Make sure
|
||||
* the right context is at work again. */
|
||||
gdk_gl_context_make_current (context);
|
||||
/* The download_texture() call may have switched the GL context. Make sure
|
||||
* the right context is at work again.
|
||||
*/
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, GDK_TEXTURE (downloaded_texture));
|
||||
}
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
|
||||
GDK_TEXTURE (downloaded_texture),
|
||||
min_filter,
|
||||
mag_filter);
|
||||
|
||||
t = gsk_gl_texture_new (texture_id,
|
||||
width, height, format, min_filter, mag_filter,
|
||||
self->current_frame_id);
|
||||
width, height,
|
||||
self->current_frame_id);
|
||||
if (ensure_mipmap)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, t->texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
t->has_mipmap = TRUE;
|
||||
}
|
||||
|
||||
g_hash_table_insert (self->textures, GUINT_TO_POINTER (texture_id), t);
|
||||
|
||||
@@ -785,7 +789,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
|
||||
g_clear_object (&downloaded_texture);
|
||||
|
||||
return texture_id;
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -794,8 +798,6 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
* @width: the width of the texture
|
||||
* @height: the height of the texture
|
||||
* @format: format for the texture
|
||||
* @min_filter: GL_NEAREST or GL_LINEAR
|
||||
* @mag_filter: GL_NEAREST or GL_FILTER
|
||||
*
|
||||
* Creates a new texture immediately that can be used by the caller
|
||||
* to upload data, map to a framebuffer, or other uses which may
|
||||
@@ -813,9 +815,7 @@ GskGLTexture *
|
||||
gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||
float width,
|
||||
float height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter)
|
||||
int format)
|
||||
{
|
||||
GskGLTexture *texture;
|
||||
guint texture_id;
|
||||
@@ -823,14 +823,11 @@ gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL);
|
||||
|
||||
texture_id = gsk_gl_command_queue_create_texture (self->command_queue,
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter);
|
||||
width, height,
|
||||
format);
|
||||
texture = gsk_gl_texture_new (texture_id,
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter,
|
||||
self->current_frame_id);
|
||||
width, height,
|
||||
self->current_frame_id);
|
||||
g_hash_table_insert (self->textures,
|
||||
GUINT_TO_POINTER (texture->texture_id),
|
||||
texture);
|
||||
@@ -876,8 +873,6 @@ gsk_gl_driver_release_texture (GskGLDriver *self,
|
||||
* @width: the width for the render target
|
||||
* @height: the height for the render target
|
||||
* @format: the format to use
|
||||
* @min_filter: the min filter to use for the texture
|
||||
* @mag_filter: the mag filter to use for the texture
|
||||
* @out_render_target: (out): a location for the render target
|
||||
*
|
||||
* Creates a new render target which contains a framebuffer and a texture
|
||||
@@ -898,8 +893,6 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
GskGLRenderTarget **out_render_target)
|
||||
{
|
||||
guint framebuffer_id;
|
||||
@@ -917,9 +910,7 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target = g_ptr_array_index (self->render_targets, i-1);
|
||||
|
||||
if (render_target->width == width &&
|
||||
render_target->height == height &&
|
||||
render_target->min_filter == min_filter &&
|
||||
render_target->mag_filter == mag_filter)
|
||||
render_target->height == height)
|
||||
{
|
||||
*out_render_target = g_ptr_array_steal_index_fast (self->render_targets, i-1);
|
||||
return TRUE;
|
||||
@@ -931,14 +922,11 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
if (gsk_gl_command_queue_create_render_target (self->command_queue,
|
||||
width, height,
|
||||
format,
|
||||
min_filter, mag_filter,
|
||||
&framebuffer_id, &texture_id))
|
||||
{
|
||||
GskGLRenderTarget *render_target;
|
||||
|
||||
render_target = g_slice_new0 (GskGLRenderTarget);
|
||||
render_target->min_filter = min_filter;
|
||||
render_target->mag_filter = mag_filter;
|
||||
render_target = g_new0 (GskGLRenderTarget, 1);
|
||||
render_target->format = format;
|
||||
render_target->width = width;
|
||||
render_target->height = height;
|
||||
@@ -999,16 +987,13 @@ gsk_gl_driver_release_render_target (GskGLDriver *self,
|
||||
texture = gsk_gl_texture_new (render_target->texture_id,
|
||||
render_target->width,
|
||||
render_target->height,
|
||||
render_target->format,
|
||||
render_target->min_filter,
|
||||
render_target->mag_filter,
|
||||
self->current_frame_id);
|
||||
g_hash_table_insert (self->textures,
|
||||
GUINT_TO_POINTER (texture_id),
|
||||
g_steal_pointer (&texture));
|
||||
|
||||
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
|
||||
g_slice_free (GskGLRenderTarget, render_target);
|
||||
g_free (render_target);
|
||||
|
||||
}
|
||||
|
||||
@@ -1195,8 +1180,7 @@ gsk_gl_driver_create_command_queue (GskGLDriver *self,
|
||||
void
|
||||
gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
gboolean ensure_mipmap,
|
||||
guint min_cols,
|
||||
guint min_rows,
|
||||
GskGLTextureSlice **out_slices,
|
||||
@@ -1228,9 +1212,12 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
|
||||
n_slices = cols * rows;
|
||||
|
||||
if ((t = gdk_texture_get_render_data (texture, self)))
|
||||
t = gdk_texture_get_render_data (texture, self);
|
||||
|
||||
if (t)
|
||||
{
|
||||
if (t->n_slices == n_slices)
|
||||
if (t->n_slices == n_slices &&
|
||||
(t->has_mipmap || !ensure_mipmap))
|
||||
{
|
||||
*out_slices = t->slices;
|
||||
*out_n_slices = t->n_slices;
|
||||
@@ -1258,10 +1245,13 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
subtex = gdk_memory_texture_new_subtexture (memtex,
|
||||
x, y,
|
||||
slice_width, slice_height);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
|
||||
subtex,
|
||||
min_filter, mag_filter);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, subtex);
|
||||
g_object_unref (subtex);
|
||||
if (ensure_mipmap)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
slices[slice_index].rect.x = x;
|
||||
slices[slice_index].rect.y = y;
|
||||
@@ -1281,9 +1271,8 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
/* Allocate one Texture for the entire thing. */
|
||||
t = gsk_gl_texture_new (0,
|
||||
tex_width, tex_height,
|
||||
GL_RGBA8,
|
||||
GL_NEAREST, GL_NEAREST,
|
||||
self->current_frame_id);
|
||||
t->has_mipmap = ensure_mipmap;
|
||||
|
||||
/* Use gsk_gl_texture_free() as destroy notify here since we are
|
||||
* not inserting this GskGLTexture into self->textures!
|
||||
@@ -1329,7 +1318,6 @@ typedef struct _GskGLTextureState
|
||||
{
|
||||
GdkGLContext *context;
|
||||
GLuint texture_id;
|
||||
GLsync sync;
|
||||
} GskGLTextureState;
|
||||
|
||||
static void
|
||||
@@ -1342,9 +1330,8 @@ create_texture_from_texture_destroy (gpointer data)
|
||||
|
||||
gdk_gl_context_make_current (state->context);
|
||||
glDeleteTextures (1, &state->texture_id);
|
||||
glDeleteSync (state->sync);
|
||||
g_clear_object (&state->context);
|
||||
g_slice_free (GskGLTextureState, state);
|
||||
g_free (state);
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
@@ -1365,7 +1352,7 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||
if (!(texture = g_hash_table_lookup (self->textures, GUINT_TO_POINTER (texture_id))))
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
state = g_slice_new0 (GskGLTextureState);
|
||||
state = g_new0 (GskGLTextureState, 1);
|
||||
state->texture_id = texture_id;
|
||||
state->context = g_object_ref (self->command_queue->context);
|
||||
|
||||
@@ -1377,13 +1364,10 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||
texture->texture_id = 0;
|
||||
gsk_gl_texture_free (texture);
|
||||
|
||||
state->sync = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
||||
return gdk_gl_texture_new_with_sync (self->command_queue->context,
|
||||
texture_id,
|
||||
state->sync,
|
||||
width,
|
||||
height,
|
||||
create_texture_from_texture_destroy,
|
||||
state);
|
||||
return gdk_gl_texture_new (self->command_queue->context,
|
||||
texture_id,
|
||||
width,
|
||||
height,
|
||||
create_texture_from_texture_destroy,
|
||||
state);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ typedef struct {
|
||||
gconstpointer pointer;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
int filter;
|
||||
int pointer_is_child;
|
||||
graphene_rect_t parent_rect; /* Valid when pointer_is_child */
|
||||
} GskTextureKey;
|
||||
@@ -86,8 +85,6 @@ struct _GskGLRenderTarget
|
||||
{
|
||||
guint framebuffer_id;
|
||||
guint texture_id;
|
||||
int min_filter;
|
||||
int mag_filter;
|
||||
int format;
|
||||
int width;
|
||||
int height;
|
||||
@@ -144,8 +141,6 @@ gboolean gsk_gl_driver_create_render_target (GskGLDriver *s
|
||||
int width,
|
||||
int height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
GskGLRenderTarget **render_target);
|
||||
guint gsk_gl_driver_release_render_target (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target,
|
||||
@@ -161,14 +156,11 @@ void gsk_gl_driver_cache_texture (GskGLDriver *s
|
||||
guint texture_id);
|
||||
guint gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
gboolean ensure_mipmap);
|
||||
GskGLTexture * gsk_gl_driver_create_texture (GskGLDriver *self,
|
||||
float width,
|
||||
float height,
|
||||
int format,
|
||||
int min_filter,
|
||||
int mag_filter);
|
||||
int format);
|
||||
void gsk_gl_driver_release_texture (GskGLDriver *self,
|
||||
GskGLTexture *texture);
|
||||
void gsk_gl_driver_release_texture_by_id (GskGLDriver *self,
|
||||
@@ -177,8 +169,7 @@ GskGLTexture * gsk_gl_driver_mark_texture_permanent (GskGLDriver *s
|
||||
guint texture_id);
|
||||
void gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
gboolean ensure_mipmap,
|
||||
guint min_cols,
|
||||
guint min_rows,
|
||||
GskGLTextureSlice **out_slices,
|
||||
@@ -232,8 +223,7 @@ gsk_gl_driver_lookup_texture (GskGLDriver *self,
|
||||
static inline void
|
||||
gsk_gl_driver_slice_texture (GskGLDriver *self,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
gboolean ensure_mipmap,
|
||||
guint min_cols,
|
||||
guint min_rows,
|
||||
GskGLTextureSlice **out_slices,
|
||||
@@ -241,17 +231,18 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
|
||||
{
|
||||
GskGLTexture *t;
|
||||
|
||||
if ((t = gdk_texture_get_render_data (texture, self)))
|
||||
t = gdk_texture_get_render_data (texture, self);
|
||||
|
||||
if (t && t->slices &&
|
||||
(t->has_mipmap || !ensure_mipmap) &&
|
||||
min_cols == 0 && min_rows == 0)
|
||||
{
|
||||
if (min_cols == 0 && min_rows == 0)
|
||||
{
|
||||
*out_slices = t->slices;
|
||||
*out_n_slices = t->n_slices;
|
||||
return;
|
||||
}
|
||||
*out_slices = t->slices;
|
||||
*out_n_slices = t->n_slices;
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_gl_driver_add_texture_slices (self, texture, min_filter, mag_filter, min_cols, min_rows, out_slices, out_n_slices);
|
||||
gsk_gl_driver_add_texture_slices (self, texture, ensure_mipmap, min_cols, min_rows, out_slices, out_n_slices);
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -74,13 +74,13 @@ gsk_gl_glyph_key_free (gpointer data)
|
||||
GskGLGlyphKey *key = data;
|
||||
|
||||
g_clear_object (&key->font);
|
||||
g_slice_free (GskGLGlyphKey, key);
|
||||
g_free (key);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyph_value_free (gpointer data)
|
||||
{
|
||||
g_slice_free (GskGLGlyphValue, data);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -88,7 +88,9 @@ gsk_gl_glyph_library_lookup_or_add (GskGLGlyphLibrary *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
GskGLGlyphKey *k = g_slice_copy (sizeof *key, key);
|
||||
GskGLGlyphKey *k;
|
||||
k = g_new (GskGLGlyphKey, 1);
|
||||
memcpy (k, key, sizeof (GskGLGlyphKey));
|
||||
g_object_ref (k->font);
|
||||
gsk_gl_glyph_library_add (self, k, out_value);
|
||||
self->front[front_index].key = *key;
|
||||
|
||||
@@ -52,7 +52,7 @@ gsk_gl_icon_data_free (gpointer data)
|
||||
GskGLIconData *icon_data = data;
|
||||
|
||||
g_clear_object (&icon_data->source_texture);
|
||||
g_slice_free (GskGLIconData, icon_data);
|
||||
g_free (icon_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -246,17 +246,21 @@ gsk_gl_program_set_uniform_color (GskGLProgram *self,
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_program_set_uniform_texture (GskGLProgram *self,
|
||||
guint key,
|
||||
guint stamp,
|
||||
GLenum texture_target,
|
||||
GLenum texture_slot,
|
||||
guint texture_id)
|
||||
gsk_gl_program_set_uniform_texture_with_filter (GskGLProgram *self,
|
||||
guint key,
|
||||
guint stamp,
|
||||
GLenum texture_target,
|
||||
GLenum texture_slot,
|
||||
guint texture_id,
|
||||
GLint min_filter,
|
||||
GLint mag_filter)
|
||||
{
|
||||
gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
|
||||
texture_target,
|
||||
texture_slot,
|
||||
texture_id);
|
||||
texture_id,
|
||||
min_filter,
|
||||
mag_filter);
|
||||
gsk_gl_uniform_state_set_texture (self->uniforms,
|
||||
self->program_info,
|
||||
key,
|
||||
@@ -265,24 +269,21 @@ gsk_gl_program_set_uniform_texture (GskGLProgram *self,
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_program_set_uniform_texture_with_sync (GskGLProgram *self,
|
||||
guint key,
|
||||
guint stamp,
|
||||
GLenum texture_target,
|
||||
GLenum texture_slot,
|
||||
guint texture_id,
|
||||
gpointer sync)
|
||||
gsk_gl_program_set_uniform_texture (GskGLProgram *self,
|
||||
guint key,
|
||||
guint stamp,
|
||||
GLenum texture_target,
|
||||
GLenum texture_slot,
|
||||
guint texture_id)
|
||||
{
|
||||
gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
|
||||
texture_target,
|
||||
texture_slot,
|
||||
texture_id);
|
||||
gsk_gl_uniform_state_set_texture (self->uniforms,
|
||||
self->program_info,
|
||||
key,
|
||||
stamp,
|
||||
texture_slot);
|
||||
gsk_gl_syncs_add_sync (&self->driver->command_queue->syncs, texture_id, sync);
|
||||
gsk_gl_program_set_uniform_texture_with_filter (self,
|
||||
key,
|
||||
stamp,
|
||||
texture_target,
|
||||
texture_slot,
|
||||
texture_id,
|
||||
GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -62,7 +62,8 @@ GSK_GL_DEFINE_PROGRAM (linear_gradient,
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (mask,
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("mask.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, MASK_SOURCE, u_mask))
|
||||
GSK_GL_ADD_UNIFORM (1, MASK_SOURCE, u_mask)
|
||||
GSK_GL_ADD_UNIFORM (2, MASK_MODE, u_mode))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (outset_shadow,
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("outset_shadow.glsl")),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user