Compare commits
619 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 91e19bc36d | |||
| 30d21ef791 | |||
| 57b419ebb1 | |||
| 9d303723b0 | |||
| 08bd1129ad | |||
| 0cb0fc8317 | |||
| 874a3837d9 | |||
| 31fc5a5a54 | |||
| 40d81f5959 | |||
| 4fad97d8ab | |||
| f1a8c95ca4 | |||
| 65a1804f05 | |||
| 92873e62ed | |||
| 0f7c33f894 | |||
| 6a83d38e7b | |||
| f89be80562 | |||
| b66fa84161 | |||
| ee7f2f9702 | |||
| 900011808a | |||
| b8ee9873f3 | |||
| 0c9faea358 | |||
| 2568611a8c | |||
| 4c64111b5b | |||
| 4f18a34dfa | |||
| bc0d315e6c | |||
| 13d72eed2d | |||
| 7bafbeffcf | |||
| f572ca52d2 | |||
| 193b383739 | |||
| 6785461c26 | |||
| b9ee9979e7 | |||
| 6bbec87700 | |||
| b35608a351 | |||
| 416763bf2d | |||
| 9179ebb28e | |||
| bcc17b3033 | |||
| 00439f9e5c | |||
| c9d748fc51 | |||
| 719eafa60c | |||
| 1759d27da9 | |||
| 53275481a5 | |||
| cbe6d0da76 | |||
| c349ed9562 | |||
| 74ce69a8a1 | |||
| 4f17f3ac24 | |||
| 9c8e464b04 | |||
| 51d0d13a9e | |||
| 0ee3b1c861 | |||
| 46f88c69a1 | |||
| 140976a670 | |||
| 9f2b847835 | |||
| 9e11ea699c | |||
| 1a4eebe022 | |||
| 2963468019 | |||
| bfbd95d7d6 | |||
| c1c1d4431d | |||
| 155a4fac5c | |||
| 76f481eb7b | |||
| 0782c8a051 | |||
| 3d27ff1177 | |||
| 3ada664a89 | |||
| 643a91bd08 | |||
| c86733b4fa | |||
| 55099b7d0e | |||
| db3858a204 | |||
| 07bff74544 | |||
| b4262883a8 | |||
| 563c85e222 | |||
| d75246a543 | |||
| b3856a3ea0 | |||
| bd4d24f8ed | |||
| 65ce3eb207 | |||
| 865ac44963 | |||
| 55a935db53 | |||
| 6fefae3dbb | |||
| f7c84ddc7f | |||
| f4a4dd2615 | |||
| b718d99d1f | |||
| c7215d1199 | |||
| 24d69ef125 | |||
| 7c3fbdecf2 | |||
| b77938f40f | |||
| f703744564 | |||
| a3ccff3773 | |||
| 9869082c1c | |||
| 754212d0f9 | |||
| a9b81577c6 | |||
| eaa2dada54 | |||
| ce2b2128bb | |||
| 41c25b8809 | |||
| b5ff35ff3e | |||
| 06423d807f | |||
| 0395395d52 | |||
| c3ca48b249 | |||
| 464e0aed04 | |||
| d46e4fcecd | |||
| 363fb96e81 | |||
| 2382bd3bb2 | |||
| 3b0a9e84ab | |||
| 850aebea5d | |||
| 26e632e549 | |||
| 64d2d7074f | |||
| 062a15310a | |||
| 299c7c3514 | |||
| 6599cb001f | |||
| f1347f5841 | |||
| f3ccf62463 | |||
| 44fea33c5d | |||
| 8b48cf11f9 | |||
| e681fdd958 | |||
| d4b7a78c54 | |||
| a45cbad553 | |||
| 16b9a30655 | |||
| 82a184a7b7 | |||
| 9e198a59b6 | |||
| c002678085 | |||
| 486cffc361 | |||
| 67495fcc77 | |||
| b26a370ce4 | |||
| 4dc0e67ac7 | |||
| 2c060663cf | |||
| 76a8eb4960 | |||
| ad3dad1965 | |||
| 172d97de05 | |||
| 4c967d5b45 | |||
| b244f31337 | |||
| 8550a04bf4 | |||
| cb38ead48e | |||
| 9713c3394d | |||
| fa57b006c9 | |||
| 9f73f0234a | |||
| a4f067481c | |||
| 733fb527fa | |||
| 3667c6b053 | |||
| 1071818df8 | |||
| 11c2d9ea30 | |||
| 52cdf3056d | |||
| 32899a1edd | |||
| 119458f13e | |||
| 2863095f06 | |||
| cbc050b9ed | |||
| 18affbd390 | |||
| 0b7a36ce33 | |||
| 1957915940 | |||
| 552b71d4e2 | |||
| 480112f9aa | |||
| 9a2f4d8026 | |||
| 3b15f32335 | |||
| 7404a6fc4f | |||
| 91d1ec41c2 | |||
| 9237c8be67 | |||
| 6c87d362c5 | |||
| 4f31d3587d | |||
| 29a2f4021a | |||
| e2d321a16a | |||
| 7366f5099a | |||
| 4fbef5f466 | |||
| 2e48ff3362 | |||
| 7cdbdb663c | |||
| 1b390d3857 | |||
| 2808f9c75b | |||
| 49d109c29e | |||
| 36dd959bf9 | |||
| 2f9a67b8a1 | |||
| 6d5d9ea073 | |||
| 1cfd340cae | |||
| 369ccfc34f | |||
| e556513de6 | |||
| 79dc1a2a4d | |||
| 9e5a501c73 | |||
| 2db8d7f6a2 | |||
| 94c3f4d4fc | |||
| 3fa26861cd | |||
| ef2b0ccd6c | |||
| f1702d24e7 | |||
| 3a50ff57d8 | |||
| 8ac2e8d495 | |||
| e56cf85fd1 | |||
| 1c6aef1862 | |||
| 4653cbe56e | |||
| 93148d302f | |||
| a443ba91ce | |||
| d8daef2de7 | |||
| 845d43c77a | |||
| f8dbcc472b | |||
| 0f0f75f6b1 | |||
| 4e2e2d84fc | |||
| 887885b6e0 | |||
| a868a5c434 | |||
| a0c147d246 | |||
| 38040c96d6 | |||
| 989ecf69ad | |||
| 9d26399143 | |||
| b9cad7cc54 | |||
| 357b97b5a6 | |||
| 318160d836 | |||
| 5e90d63373 | |||
| 0b7f1e488f | |||
| e281bbbb55 | |||
| 892bacee52 | |||
| 2f1db4b77c | |||
| f90e9b26f8 | |||
| ad71f454bd | |||
| c66bd791c4 | |||
| 40bceef3ca | |||
| 9d79f55dc9 | |||
| c5c1cf6d55 | |||
| 9eb8aa9a32 | |||
| 95931a7e6c | |||
| d9daaed43f | |||
| b9c51e65c1 | |||
| da5eb92f47 | |||
| 03ed585f6f | |||
| 51f953a1aa | |||
| 93fb07d808 | |||
| 5e311d4d85 | |||
| e652054d50 | |||
| 58c31b8627 | |||
| b945033b41 | |||
| 92d2867170 | |||
| 5d38c8c558 | |||
| 552a4b2c82 | |||
| 7a4afb08bd | |||
| c5cd1ac630 | |||
| 90edb76415 | |||
| 8f397502df | |||
| 1cb17d8613 | |||
| 88e796bb45 | |||
| 1310bf0218 | |||
| 4efeaa844f | |||
| 24685612a9 | |||
| bf21df4195 | |||
| 417b3f9c6b | |||
| 2d84a1c63e | |||
| 5ab9a29bc4 | |||
| 383ea0d86a | |||
| df8f75bb8f | |||
| ba95ef63da | |||
| bea4aa31ea | |||
| 6c19a8352f | |||
| e3df89b524 | |||
| a9003f7ac0 | |||
| 2cc06f60c5 | |||
| 4759afcc3e | |||
| 66b297e408 | |||
| bbd2b255a3 | |||
| 8b2f28eee3 | |||
| ae767dc5bf | |||
| d923402934 | |||
| 9667f889b3 | |||
| d2ea7af335 | |||
| f95e9407a9 | |||
| 7be3c2974a | |||
| 5444f604cb | |||
| 94e68b0e36 | |||
| 910d86f958 | |||
| fd885e42b0 | |||
| ea31ae31c1 | |||
| 00763e5af3 | |||
| 1bf5aab18c | |||
| 210a709246 | |||
| 5feba67a3d | |||
| e9e373913e | |||
| f1f197e3b9 | |||
| cedb6183e9 | |||
| 0415d46c0f | |||
| 68388331c7 | |||
| 92817b0603 | |||
| f8a1726ffa | |||
| be34f27026 | |||
| 12c5518e2b | |||
| d8ab5c3c45 | |||
| 36d1c9e8b7 | |||
| 45c047f5c0 | |||
| da1232caaf | |||
| fff5a83957 | |||
| f5b6488eb2 | |||
| c02bae9e08 | |||
| 58e65ae7dd | |||
| 3977518f00 | |||
| 8adee3dace | |||
| 09ad930da4 | |||
| 52f7bb6950 | |||
| 68db945e47 | |||
| b54f4cf5d4 | |||
| 9a8a9451b1 | |||
| fffa903ce9 | |||
| ab08885a32 | |||
| ad3995b1b9 | |||
| 75cc0710ac | |||
| 7cec7054e2 | |||
| fe280e578f | |||
| a32973f56b | |||
| 7762311911 | |||
| edd73ffbed | |||
| fca87d93e9 | |||
| c2fe2c0385 | |||
| 8aa25046dc | |||
| 27a07ed89c | |||
| 071a6bcc06 | |||
| f98ac6590d | |||
| 6b733d2943 | |||
| 6f165efcdb | |||
| 7bc1c9a562 | |||
| 1596fdeba3 | |||
| 1599b659cf | |||
| bb65564c7d | |||
| 03031b3dc1 | |||
| b7636ebbc0 | |||
| 5707b80a69 | |||
| 81e5d4c327 | |||
| f8111125ef | |||
| c020e83890 | |||
| f6659fea8d | |||
| a06858ccd9 | |||
| c6c48d327c | |||
| 5d0f188615 | |||
| 78fcc8feb8 | |||
| 27cad85247 | |||
| ad0c1d4dbe | |||
| 00abaed89a | |||
| 342f02711b | |||
| d9c48a8d01 | |||
| d757696116 | |||
| 528ebfabf0 | |||
| 2ebde276d1 | |||
| 04f3c8054b | |||
| ea07bf7536 | |||
| 80e6f1ca8c | |||
| 54d29568ec | |||
| 4e1ea58503 | |||
| 90c429a91c | |||
| 4b28e038e0 | |||
| 8df694a358 | |||
| eb8778e1cd | |||
| 256f3a0d60 | |||
| 54c087e7ec | |||
| 69a99b89f9 | |||
| f328ab9d83 | |||
| 8acce5f294 | |||
| bdbe0acd1f | |||
| fc701baef8 | |||
| a457a81fd9 | |||
| 4cc7977d36 | |||
| e5e7f5dd88 | |||
| 916886312a | |||
| 8ff94ea1f2 | |||
| 053bd0cd31 | |||
| a3ce574193 | |||
| ef92adc87d | |||
| 46a9538b6a | |||
| ca547b8716 | |||
| 04ea51e843 | |||
| f7dc0dda4e | |||
| 8713843022 | |||
| 6563b05d60 | |||
| d119c55b72 | |||
| 253e25a73c | |||
| c63774967f | |||
| bbc36448fb | |||
| 5df323fb64 | |||
| 0f2c5f13be | |||
| 58180ad3be | |||
| fb0229890b | |||
| 9099888398 | |||
| 882855f865 | |||
| f59d2ae89d | |||
| 7c3a53a171 | |||
| 1e22572716 | |||
| 8a25f54e1f | |||
| c51f2fc0ec | |||
| 2a528df977 | |||
| 84684bd56e | |||
| e1606ce8eb | |||
| 47072e0441 | |||
| 915c229396 | |||
| 0bf46b4845 | |||
| a7a2dbc3ea | |||
| 7e8f586859 | |||
| bb9dccd773 | |||
| 7b743e662e | |||
| 769dc53c05 | |||
| 1a4554daf3 | |||
| 6c0633ef61 | |||
| 4d020a3875 | |||
| 316cc55e69 | |||
| 95f2634ea9 | |||
| 95c032f531 | |||
| 744955753f | |||
| ae5e7dc65d | |||
| ed41c46926 | |||
| a460fb2734 | |||
| 39ddce6ba3 | |||
| 8da7e3bdc3 | |||
| eff53c023a | |||
| 99e4a6a2d6 | |||
| c06817b951 | |||
| e765aaa3f4 | |||
| 1728aa581c | |||
| c50475de34 | |||
| 5d7ecb7a6e | |||
| 06348a8517 | |||
| c4dbb8f01e | |||
| e67b2cb54b | |||
| 908b1e5e12 | |||
| 539391ce6c | |||
| 7fc90aed26 | |||
| 23e79d2eb2 | |||
| 0c7b1431d7 | |||
| b6c0155836 | |||
| 76d67b586c | |||
| 914edb1472 | |||
| dbf5033f94 | |||
| cc6ecc8b62 | |||
| b7e6922605 | |||
| 05eaffb9f2 | |||
| 67b568f464 | |||
| 19b534f7de | |||
| bc386c9a60 | |||
| db8b3419c2 | |||
| 0f5ba5192a | |||
| 108c423d70 | |||
| dded10a396 | |||
| 1b080826db | |||
| 910f23ea19 | |||
| f1b50baba1 | |||
| 4453597946 | |||
| 192bfa10cb | |||
| 0781429dc5 | |||
| d760332f00 | |||
| 131be5f2e8 | |||
| 57a95c540c | |||
| 09deb1d757 | |||
| 5c4aba4b9c | |||
| 6a5d555f58 | |||
| f5dc71021f | |||
| 39005461c5 | |||
| 4dc4c00267 | |||
| d76460343a | |||
| 0d8dd0c664 | |||
| ee6491f717 | |||
| 7044951dab | |||
| 98986a25f9 | |||
| ae3e586714 | |||
| 0ef12193f9 | |||
| b695ef9168 | |||
| 7fb1389648 | |||
| f88efb811b | |||
| 466d33ca69 | |||
| d44ce1987d | |||
| 527b2c5ab1 | |||
| 4d0c2997cf | |||
| 6f04ec9dae | |||
| 00cc99818d | |||
| e51fdc1c9b | |||
| 8d5ef4ab30 | |||
| 7bdda15b86 | |||
| 4c41ef8de3 | |||
| 7aec3b0fa1 | |||
| fce23c981b | |||
| 351819b570 | |||
| a10b1b7341 | |||
| 02c6226741 | |||
| 620ccdabb5 | |||
| 4b12dc6547 | |||
| bd69d7e23f | |||
| 8648486400 | |||
| 6c00117119 | |||
| 9c4c4eaaa1 | |||
| 969b3257a7 | |||
| 65c6af31e1 | |||
| 6b8bc83420 | |||
| 30aaab5c6c | |||
| 72e2a46c05 | |||
| e06e0e8555 | |||
| 9f1d6e1f44 | |||
| 15ed1a329e | |||
| 505436340b | |||
| a27434a8a7 | |||
| 2c987861a6 | |||
| c7320df0c9 | |||
| dd666e4fe4 | |||
| e4f0418003 | |||
| 430b6f8fb1 | |||
| ba3e80cbfa | |||
| 7cd4282bad | |||
| 01e9fa9adb | |||
| 581e01b2da | |||
| 5a3b4de1b7 | |||
| 74288eceaf | |||
| 37ba057128 | |||
| 6d5ba9590b | |||
| 215f792851 | |||
| 1c55b32879 | |||
| 82eb947f41 | |||
| 485dae9f25 | |||
| eb3423312f | |||
| 04c2093d5c | |||
| ccd5992a83 | |||
| ca8d9fbe0b | |||
| 62bac44a21 | |||
| 0ddd06113d | |||
| b1fbc2ef24 | |||
| c787fe7ecb | |||
| bdb49720be | |||
| 1d448a2b8a | |||
| c5df081904 | |||
| 8a2f3e1fe5 | |||
| 8dfc627e46 | |||
| 0fce30070f | |||
| 8bfe82f686 | |||
| 7d32ec51e7 | |||
| 5784f8c2f9 | |||
| 74e01ddec5 | |||
| 1347573139 | |||
| f2b41e708d | |||
| a5555943ed | |||
| 2c023cdaed | |||
| bcc7028640 | |||
| bdee75cd0f | |||
| 94eb3d7ac0 | |||
| 0ae2acfb1a | |||
| afc5f46ca9 | |||
| e544c891ca | |||
| af0c95c11a | |||
| 4d5dc18a57 | |||
| 9f6fb161e2 | |||
| 3883a98771 | |||
| 9b44965f13 | |||
| aa6a9de6ba | |||
| 8669e8a498 | |||
| ead31db096 | |||
| 69fda941c7 | |||
| 67c9e7a4a8 | |||
| 4e4f57e091 | |||
| ac64d2d910 | |||
| 49a76257cd | |||
| 77829cf3ed | |||
| 4d10ab3d35 | |||
| e609ede597 | |||
| 2ba69abe39 | |||
| a76f515569 | |||
| a663b8c313 | |||
| f66fa16bd1 | |||
| 8390363abe | |||
| 6ff85d287a | |||
| 94c2072be8 | |||
| 64b9d53472 | |||
| a5e7b92c5d | |||
| 2da9ba63e2 | |||
| 5d02a8f5db | |||
| 834d3749c6 | |||
| 1c90bb522e | |||
| b70b058b66 | |||
| b99beeb552 | |||
| c799452973 | |||
| fd48afb77d | |||
| aaa68954c3 | |||
| 433233258b | |||
| 3eed61deba | |||
| 87e2a02e0c | |||
| 264d592012 | |||
| 0ad5094119 | |||
| 67952a9142 | |||
| ca3d942b9b | |||
| 5470a1344d | |||
| 4390f8102b | |||
| 92129a2011 | |||
| 54dffa07f3 | |||
| 1cff4bb27a | |||
| 8087250476 | |||
| 485dc052ca | |||
| 45d39c2802 | |||
| 3b4b1c6878 | |||
| ff4f07d76f | |||
| fb6c8cd466 | |||
| 8464b0484f | |||
| bee58fd09d | |||
| d25557a5ef | |||
| da3ca6604b | |||
| 74cba6c3b2 | |||
| c09718b731 | |||
| eacfa2a966 | |||
| e7f228e240 | |||
| fab82a7c25 | |||
| fc9c34897a | |||
| 28cdd3f497 | |||
| a009e26e95 | |||
| ab908c23f4 | |||
| ae21f66fe5 | |||
| 2d092ea280 | |||
| 0f9d39cdfd | |||
| a64087d481 | |||
| c85f3f4942 | |||
| d7553279ff | |||
| c86631b8a9 | |||
| c1af63de9b | |||
| 2784b03b2d | |||
| 10bdf8c645 | |||
| d63d9b2319 | |||
| d5f2b69d0c | |||
| 6818eee859 | |||
| e7f1398d85 | |||
| 880c01f8cc | |||
| 337c5e5e59 | |||
| af52ea78c6 | |||
| fe633d9ef9 | |||
| e6cce283a7 | |||
| c920236c54 | |||
| 6f86b4d220 | |||
| a085e174c5 | |||
| d3c08789a3 | |||
| 630488210b | |||
| 873f6ccfea | |||
| af15f5d004 | |||
| f328175e2f | |||
| fc65d6393a | |||
| 271afb7eab | |||
| 76133dbea7 |
+9
-9
@@ -7,6 +7,7 @@ stages:
|
||||
- analysis
|
||||
- docs
|
||||
- flatpak
|
||||
- publish
|
||||
- deploy
|
||||
|
||||
.cache-paths: &cache-paths
|
||||
@@ -24,7 +25,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v32"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v33"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
|
||||
.only-default:
|
||||
@@ -57,6 +58,7 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/report*.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report*.html"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
||||
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
|
||||
@@ -172,6 +174,7 @@ macos:
|
||||
- meson -Dx11-backend=false
|
||||
-Dbroadway-backend=true
|
||||
-Dmacos-backend=true
|
||||
-Dmedia-gstreamer=disabled
|
||||
-Dintrospection=disabled
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
@@ -335,14 +338,11 @@ reference:
|
||||
paths:
|
||||
- _reference
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
publish-docs:
|
||||
stage: publish
|
||||
needs: ['reference']
|
||||
script:
|
||||
- mv _reference/ public/
|
||||
- cp .gitlab-ci/pages/* public/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
|
||||
only:
|
||||
- master
|
||||
refs:
|
||||
- master
|
||||
|
||||
@@ -48,7 +48,9 @@ RUN dnf -y install \
|
||||
libcloudproviders-devel \
|
||||
libepoxy-devel \
|
||||
libffi-devel \
|
||||
libjpeg-turbo-devel \
|
||||
libmount-devel \
|
||||
libpng-devel \
|
||||
librsvg2 \
|
||||
libselinux-devel \
|
||||
libubsan \
|
||||
|
||||
@@ -15,7 +15,7 @@ meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
-Dvulkan=enabled \
|
||||
-Dprofiler=true \
|
||||
--werror \
|
||||
${EXTRA_MESON_FLAGS:-} \
|
||||
|
||||
@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson==0.56.2 || goto :error
|
||||
meson _build || goto :error
|
||||
meson -Dmedia-gstreamer=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
goto :EOF
|
||||
|
||||
@@ -40,7 +40,7 @@ export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
# https://gitlab.gnome.org/GNOME/gtk/-/issues/2243
|
||||
# https://gitlab.gnome.org/GNOME/gtk/-/issues/3002
|
||||
|
||||
if ! pkg-config --atleast-version=2.65.0 glib-2.0; then
|
||||
if ! pkg-config --atleast-version=2.66.0 glib-2.0; then
|
||||
git clone https://gitlab.gnome.org/GNOME/glib.git _glib
|
||||
meson setup _glib_build _glib
|
||||
meson compile -C _glib_build
|
||||
@@ -48,7 +48,7 @@ if ! pkg-config --atleast-version=2.65.0 glib-2.0; then
|
||||
fi
|
||||
pkg-config --modversion glib-2.0
|
||||
|
||||
if ! pkg-config --atleast-version=1.47.0 pango; then
|
||||
if ! pkg-config --atleast-version=1.49.1 pango; then
|
||||
git clone https://gitlab.gnome.org/GNOME/pango.git _pango
|
||||
meson setup _pango_build _pango
|
||||
meson compile -C _pango_build
|
||||
|
||||
@@ -1,3 +1,191 @@
|
||||
Overview of Changes
|
||||
===================
|
||||
|
||||
* gsk:
|
||||
- Drop the GL renderer in favor of NGL
|
||||
|
||||
* css:
|
||||
- Add support for line-height
|
||||
- Add support for text-transform
|
||||
|
||||
* GtkTextView:
|
||||
- Add support for line height
|
||||
- Add support for text transforms
|
||||
|
||||
* Build:
|
||||
- Require Pango 1.49
|
||||
|
||||
|
||||
Overview of Changes in 4.4.0
|
||||
============================
|
||||
|
||||
* Input:
|
||||
- Match IBus for display of Compose sequences
|
||||
- Match IBus for handling of mismatches
|
||||
- Handle Escape in Compose sequences
|
||||
- Allow multiple dead keys
|
||||
- Support 32bit keysyms
|
||||
|
||||
* GtkCheckButton:
|
||||
- Activate when moving focus
|
||||
|
||||
* GtkLabel:
|
||||
- Propertly ignore double underscores for mnemonics
|
||||
|
||||
* GtkPopoverMenu:
|
||||
- Fix focus cycling
|
||||
|
||||
* GtkTextView:
|
||||
- Improve word selection
|
||||
- Fix block cursors on empty lines
|
||||
|
||||
* GdkToplevel:
|
||||
- Support the gnome-shell titlebar gesture protocol
|
||||
|
||||
* GdkDropTarget:
|
||||
- Allow creating drop targets in ui files
|
||||
|
||||
* gsk:
|
||||
- Handle partial color fonts correctly
|
||||
- Use harfbuzz for color font information
|
||||
- Avoid pango for glyph cache rendering
|
||||
- Shrink shadow extents
|
||||
|
||||
* Settings:
|
||||
- Change the default for gtk-split-cursor to FALSE
|
||||
|
||||
* Demos:
|
||||
- Small improvements to widget-factory
|
||||
- gtk-demo: Improve the hypertext demo
|
||||
- gtk-dem: Improve the clipboard demo
|
||||
|
||||
* X11:
|
||||
- Set WM_CLASS on toplevels
|
||||
|
||||
* Wayland:
|
||||
- Support wl_seat v7
|
||||
|
||||
* Windows:
|
||||
- Drop the local DND protocol
|
||||
- Avoid WGL if shaders don't work
|
||||
- Use WinPointer API
|
||||
|
||||
* Translation updates:
|
||||
Belarusian
|
||||
Friulian
|
||||
Hebrew
|
||||
Khmer
|
||||
Persian
|
||||
Polish
|
||||
|
||||
|
||||
Overview of Changes in 4.3.2
|
||||
============================
|
||||
|
||||
* GtkToggleButton:
|
||||
- Fix the actionable implementation
|
||||
|
||||
* GtkCheckButton:
|
||||
- Fix the actionable implementation
|
||||
- Cancel activation on when the pointer leaves
|
||||
|
||||
* GtkMenuButton:
|
||||
- Make activatable again
|
||||
- Add a way to have an icon + arrow
|
||||
|
||||
* GtkColorButton:
|
||||
- Make activatable again
|
||||
|
||||
* GtkFontButton:
|
||||
- Make activatable again
|
||||
|
||||
* GtkAppChooserButton:
|
||||
- Make activatable again
|
||||
|
||||
* GtkColumnView:
|
||||
- Fix double activation
|
||||
|
||||
* GtkLabel:
|
||||
- Fix mnemonics without markup
|
||||
|
||||
* GtkTreeView:
|
||||
- Clip header buttons
|
||||
|
||||
* GtkTextView:
|
||||
- Add api to get the RTL and LTR contexts
|
||||
- Fix some errors in text history grouping
|
||||
|
||||
* GtkText:
|
||||
- Don't show placeholder text on top of entry text
|
||||
- Add api to compute the cursor extents
|
||||
- Fix y coordinates for text selection
|
||||
|
||||
* GtkFileChooser:
|
||||
- Don't show Trash in the side bar
|
||||
|
||||
* GtkPopoverMenu:
|
||||
- Add scrollbars to long menus
|
||||
|
||||
* GtkActionMuxer:
|
||||
- Fix propagation of accel changes
|
||||
|
||||
* Introspection:
|
||||
- Annotate all filename arguments
|
||||
- Rename GtkMediaStream apis to avoid name collisions
|
||||
- Rename GtkDropTarget properties to avoid name collisions
|
||||
- Make GtkPasswordEntryBuffer introspectable
|
||||
|
||||
* Printing:
|
||||
- Remove the Google Cloud Print backend
|
||||
|
||||
* Theme:
|
||||
- Sync included icons with the Adwaita icon theme
|
||||
|
||||
* GSK:
|
||||
- Avoid overflowing the vertex counter
|
||||
- Handle negative scales correctly in the ngl renderer
|
||||
|
||||
* GDK:
|
||||
- Cleanup and simplify OpenGL setup code
|
||||
- Add a GdkDisplay::init_gl vfunc and gdk_display_prepare_gl() api
|
||||
- Require EGL 1.4
|
||||
- Fix EGL + NVidia
|
||||
|
||||
* Build:
|
||||
- Enable gstreamer by default
|
||||
- Disable Vulkan by default
|
||||
- Remove the sassc option
|
||||
- Remove options and checks for X11 extensions
|
||||
|
||||
* X11:
|
||||
- Stop using XComposite
|
||||
- Remove the Visual cache
|
||||
|
||||
* Wayland:
|
||||
- Fix some DND corner cases
|
||||
- Work with version 2 of pointer-gestures-v1
|
||||
- Look for cursor themes in $HOME/.icons
|
||||
|
||||
* Windows:
|
||||
- Fix SIGILL on x64 due to popcnt
|
||||
- Fix popup placement
|
||||
- Fix drag icon placement
|
||||
- Clean up HiDPI and WGL support
|
||||
- Default to WGL
|
||||
|
||||
* MacOs:
|
||||
- Fix input method support
|
||||
- Register known clipboard types for drop targets
|
||||
- Add initial DND support
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
Portuguese
|
||||
Romanian
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.3.1
|
||||
============================
|
||||
|
||||
|
||||
-289
@@ -1,289 +0,0 @@
|
||||
/* always defined to indicate that i18n is enabled */
|
||||
#define ENABLE_NLS 1
|
||||
|
||||
/* Use structured logging */
|
||||
#define G_LOG_STRUCTURED 1
|
||||
|
||||
/* The prefix for our gettext translation domains. */
|
||||
#mesondefine GETTEXT_PACKAGE
|
||||
|
||||
/* Disable deprecation warnings from glib */
|
||||
#mesondefine GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
/* Define the location where the catalogs will be installed */
|
||||
#mesondefine GTK_LOCALEDIR
|
||||
|
||||
/* Define to 1 if you have the `bind_textdomain_codeset' function. */
|
||||
#mesondefine HAVE_BIND_TEXTDOMAIN_CODESET
|
||||
|
||||
/* Have the cloudproviders library */
|
||||
#mesondefine HAVE_CLOUDPROVIDERS
|
||||
|
||||
/* define if we have colord */
|
||||
#mesondefine HAVE_COLORD
|
||||
|
||||
/* Define to 1 if you have the <crt_externs.h> header file. */
|
||||
#mesondefine HAVE_CRT_EXTERNS_H
|
||||
|
||||
/* Define to 1 if you have the `dcgettext' function. */
|
||||
#mesondefine HAVE_DCGETTEXT
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#mesondefine HAVE_DLFCN_H
|
||||
|
||||
/* Have the ffmpeg library */
|
||||
#mesondefine HAVE_FFMPEG
|
||||
|
||||
/* Define to 1 if you have the <ftw.h> header file. */
|
||||
#mesondefine HAVE_FTW_H
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#mesondefine HAVE_GETPAGESIZE
|
||||
|
||||
/* Define to 1 if you have the `getresuid' function. */
|
||||
#mesondefine HAVE_GETRESUID
|
||||
|
||||
/* Define if gio-unix is available */
|
||||
#mesondefine HAVE_GIO_UNIX
|
||||
|
||||
/* Define if GStreamer support is available */
|
||||
#mesondefine HAVE_GSTREAMER
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#mesondefine HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if the system has the type `IPrintDialogCallback'. */
|
||||
#mesondefine HAVE_IPRINTDIALOGCALLBACK
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#mesondefine HAVE_LOCALE_H
|
||||
|
||||
/* Define to 1 if you have the `lstat' function. */
|
||||
#mesondefine HAVE_LSTAT
|
||||
|
||||
/* Define to 1 if you have the `mallinfo' function. */
|
||||
#mesondefine HAVE_MALLINFO
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#mesondefine HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mkstemp' function. */
|
||||
#mesondefine HAVE_MKSTEMP
|
||||
|
||||
/* Define to 1 if you have the `mlock` function. */
|
||||
#mesondefine HAVE_MLOCK
|
||||
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#mesondefine HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have a working `madvise' system call. */
|
||||
#mesondefine HAVE_MADVISE
|
||||
|
||||
/* Define to 1 if you have the `posix_fallocate' function. */
|
||||
#mesondefine HAVE_POSIX_FALLOCATE
|
||||
|
||||
/* Have the Xrandr extension library */
|
||||
#mesondefine HAVE_RANDR
|
||||
|
||||
/* Have the Xrandr 1.5 extension library */
|
||||
#mesondefine HAVE_RANDR15
|
||||
|
||||
/* Define to 1 if you have the `sincos' function. */
|
||||
#mesondefine HAVE_SINCOS
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#mesondefine HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#mesondefine HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#mesondefine HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#mesondefine HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#mesondefine HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#mesondefine HAVE_SYS_PARAM_H
|
||||
|
||||
/* Have the sysprof-capture library */
|
||||
#mesondefine HAVE_SYSPROF
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#mesondefine HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#mesondefine HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#mesondefine HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#mesondefine HAVE_UNISTD_H
|
||||
|
||||
/* Have the XCOMPOSITE X extension */
|
||||
#mesondefine HAVE_XCOMPOSITE
|
||||
|
||||
/* Have the Xcursor library */
|
||||
#mesondefine HAVE_XCURSOR
|
||||
|
||||
/* Have the XDAMAGE X extension */
|
||||
#mesondefine HAVE_XDAMAGE
|
||||
|
||||
/* Have the XFIXES X extension */
|
||||
#mesondefine HAVE_XFIXES
|
||||
|
||||
/* Define to 1 if XFree Xinerama is available */
|
||||
#mesondefine HAVE_XFREE_XINERAMA
|
||||
|
||||
/* Have XGenericEvent */
|
||||
#mesondefine HAVE_XGENERICEVENTS
|
||||
|
||||
/* Define to use XKB extension */
|
||||
#mesondefine HAVE_XKB
|
||||
|
||||
/* Have the SYNC extension library */
|
||||
#mesondefine HAVE_XSYNC
|
||||
|
||||
/* Define to 1 if you have the `_lock_file' function */
|
||||
#mesondefine HAVE__LOCK_FILE
|
||||
|
||||
/* Define to 1 if you have the `flockfile' function */
|
||||
#mesondefine HAVE_FLOCKFILE
|
||||
|
||||
/* Define if _NL_MEASUREMENT_MEASUREMENT is available */
|
||||
#mesondefine HAVE__NL_MEASUREMENT_MEASUREMENT
|
||||
|
||||
/* Define if _NL_PAPER_HEIGHT is available */
|
||||
#mesondefine HAVE__NL_PAPER_HEIGHT
|
||||
|
||||
/* Define if _NL_PAPER_WIDTH is available */
|
||||
#mesondefine HAVE__NL_PAPER_WIDTH
|
||||
|
||||
/* Define if _NL_TIME_FIRST_WEEKDAY is available */
|
||||
#mesondefine HAVE__NL_TIME_FIRST_WEEKDAY
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#mesondefine LT_OBJDIR
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#mesondefine NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#mesondefine PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#mesondefine PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#mesondefine PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#mesondefine PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#mesondefine PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#mesondefine PACKAGE_VERSION
|
||||
|
||||
/* Use NSBundle functions to determine load paths for libraries, translations,
|
||||
etc. */
|
||||
#mesondefine QUARTZ_RELOCATION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#mesondefine STDC_HEADERS
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 if XInput 2.2 is available */
|
||||
#mesondefine XINPUT_2_2
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
#mesondefine X_DISPLAY_MISSING
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#mesondefine _FILE_OFFSET_BITS
|
||||
|
||||
/* defines how to decorate public symbols while building */
|
||||
#mesondefine _GDK_EXTERN
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#mesondefine _LARGE_FILES
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#mesondefine _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#mesondefine _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#mesondefine _POSIX_SOURCE
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#mesondefine gid_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#mesondefine uid_t
|
||||
|
||||
/* Define to 1 if linux/memfd.h exists */
|
||||
#mesondefine HAVE_LINUX_MEMFD_H
|
||||
|
||||
#mesondefine HAVE_LINUX_INPUT_H
|
||||
|
||||
#mesondefine HAVE_DEV_EVDEV_INPUT_H
|
||||
|
||||
#mesondefine GTK_SYSCONFDIR
|
||||
|
||||
#mesondefine GTK_LOCALEDIR
|
||||
|
||||
#mesondefine GTK_DATADIR
|
||||
|
||||
#mesondefine GTK_LIBDIR
|
||||
|
||||
#mesondefine GTK_PRINT_BACKENDS
|
||||
|
||||
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
|
||||
|
||||
#mesondefine HAVE_HARFBUZZ
|
||||
|
||||
#mesondefine HAVE_PANGOFT
|
||||
|
||||
#mesondefine ISO_CODES_PREFIX
|
||||
|
||||
/* Define if tracker3 is available */
|
||||
#mesondefine HAVE_TRACKER3
|
||||
|
||||
#mesondefine HAVE_F16C
|
||||
|
||||
/* Does the OS support GDesktopAppInfo? */
|
||||
#mesondefine HAVE_DESKTOPAPPINFO
|
||||
@@ -321,6 +321,7 @@
|
||||
<file>paintable_emblem.c</file>
|
||||
<file>paintable_mediastream.c</file>
|
||||
<file>paintable_svg.c</file>
|
||||
<file>paintable_symbolic.c</file>
|
||||
<file>panes.c</file>
|
||||
<file>password_entry.c</file>
|
||||
<file>peg_solitaire.c</file>
|
||||
|
||||
+42
-12
@@ -100,7 +100,11 @@ prepare_drag (GtkDragSource *source,
|
||||
DemoImage *demo = DEMO_IMAGE (widget);
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
|
||||
/* Textures can be serialized, paintables can't, so special case the textures */
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
|
||||
else
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -129,7 +133,11 @@ copy_image (GtkWidget *widget,
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
||||
/* Textures can be serialized, paintables can't, so special case the textures */
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
g_value_init (&value, GDK_TYPE_TEXTURE);
|
||||
else
|
||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
||||
g_value_set_object (&value, paintable);
|
||||
gdk_clipboard_set_value (clipboard, &value);
|
||||
g_value_unset (&value);
|
||||
@@ -138,24 +146,46 @@ copy_image (GtkWidget *widget,
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||
DemoImage *demo = DEMO_IMAGE (data);
|
||||
const GValue *value;
|
||||
|
||||
value = gdk_clipboard_read_value_finish (clipboard, result, NULL);
|
||||
if (value == NULL)
|
||||
{
|
||||
gtk_widget_error_bell (GTK_WIDGET (demo));
|
||||
g_object_unref (demo);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), g_value_get_object (value));
|
||||
g_object_unref (demo);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
DemoImage *demo = DEMO_IMAGE (widget);
|
||||
GdkContentProvider *content = gdk_clipboard_get_content (clipboard);
|
||||
GValue value = G_VALUE_INIT;
|
||||
GdkPaintable *paintable;
|
||||
GType type;
|
||||
|
||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
||||
if (!gdk_content_provider_get_value (content, &value, NULL))
|
||||
return;
|
||||
if (gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GDK_TYPE_TEXTURE))
|
||||
type = GDK_TYPE_TEXTURE;
|
||||
else
|
||||
type = GDK_TYPE_PAINTABLE;
|
||||
|
||||
paintable = GDK_PAINTABLE (g_value_get_object (&value));
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
|
||||
g_value_unset (&value);
|
||||
gdk_clipboard_read_value_async (clipboard,
|
||||
type,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
paste_image_cb,
|
||||
g_object_ref (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -131,6 +131,19 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
#define VOID_ATTR(attr_name) \
|
||||
{ \
|
||||
tag = gtk_text_tag_table_lookup (table, #attr_name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (#attr_name); \
|
||||
g_object_set (tag, #attr_name, TRUE, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
fg_alpha = bg_alpha = 1.;
|
||||
|
||||
attrs = pango_attr_iterator_get_attrs (iter);
|
||||
@@ -255,6 +268,29 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
INT_ATTR (insert_hyphens);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_LINE_HEIGHT:
|
||||
FLOAT_ATTR (line_height);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_WORD:
|
||||
VOID_ATTR (word);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_SENTENCE:
|
||||
VOID_ATTR (sentence);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_BASELINE_SHIFT:
|
||||
INT_ATTR (baseline_shift);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_FONT_SCALE:
|
||||
INT_ATTR (font_scale);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_SHAPE:
|
||||
case PANGO_ATTR_ABSOLUTE_SIZE:
|
||||
case PANGO_ATTR_GRAVITY:
|
||||
@@ -263,6 +299,10 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
case PANGO_ATTR_BACKGROUND_ALPHA:
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_TEXT_TRANSFORM:
|
||||
INT_ATTR (text_transform);
|
||||
break;
|
||||
|
||||
case PANGO_ATTR_INVALID:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
|
||||
+163
-13
@@ -1,6 +1,11 @@
|
||||
/* Pango/Font Rendering
|
||||
*
|
||||
* Demonstrates various aspects of font rendering.
|
||||
* Demonstrates various aspects of font rendering,
|
||||
* such as hinting, antialiasing and grid alignment.
|
||||
*
|
||||
* The demo lets you explore font rendering options
|
||||
* interactively to get a feeling for they affect the
|
||||
* shape and positioning of the glyphs.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -10,16 +15,21 @@ static GtkWidget *font_button = NULL;
|
||||
static GtkWidget *entry = NULL;
|
||||
static GtkWidget *image = NULL;
|
||||
static GtkWidget *hinting = NULL;
|
||||
static GtkWidget *anti_alias = NULL;
|
||||
static GtkWidget *hint_metrics = NULL;
|
||||
static GtkWidget *up_button = NULL;
|
||||
static GtkWidget *down_button = NULL;
|
||||
static GtkWidget *text_radio = NULL;
|
||||
static GtkWidget *show_grid = NULL;
|
||||
static GtkWidget *show_extents = NULL;
|
||||
static GtkWidget *show_pixels = NULL;
|
||||
static GtkWidget *show_outlines = NULL;
|
||||
|
||||
static PangoContext *context;
|
||||
|
||||
static int scale = 9;
|
||||
static int scale = 7;
|
||||
static double pixel_alpha = 1.0;
|
||||
static double outline_alpha = 0.0;
|
||||
|
||||
static void
|
||||
update_image (void)
|
||||
@@ -37,6 +47,8 @@ update_image (void)
|
||||
cairo_font_options_t *fopt;
|
||||
cairo_hint_style_t hintstyle;
|
||||
cairo_hint_metrics_t hintmetrics;
|
||||
cairo_antialias_t antialias;
|
||||
cairo_path_t *path;
|
||||
|
||||
if (!context)
|
||||
context = gtk_widget_create_pango_context (image);
|
||||
@@ -65,6 +77,13 @@ update_image (void)
|
||||
hintmetrics = CAIRO_HINT_METRICS_OFF;
|
||||
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
|
||||
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (anti_alias)))
|
||||
antialias = CAIRO_ANTIALIAS_GRAY;
|
||||
else
|
||||
antialias = CAIRO_ANTIALIAS_NONE;
|
||||
cairo_font_options_set_antialias (fopt, antialias);
|
||||
|
||||
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
|
||||
pango_cairo_context_set_font_options (context, fopt);
|
||||
cairo_font_options_destroy (fopt);
|
||||
pango_context_changed (context);
|
||||
@@ -85,10 +104,14 @@ update_image (void)
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, pixel_alpha);
|
||||
|
||||
cairo_move_to (cr, 10, 10);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
pango_cairo_layout_path (cr, layout);
|
||||
path = cairo_copy_path (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
g_object_unref (layout);
|
||||
|
||||
@@ -127,7 +150,7 @@ update_image (void)
|
||||
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (show_extents)))
|
||||
{
|
||||
cairo_set_source_rgba (cr, 0, 0, 1, 1);
|
||||
cairo_set_source_rgb (cr, 0, 0, 1);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
@@ -140,7 +163,7 @@ update_image (void)
|
||||
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_stroke (cr);
|
||||
cairo_set_source_rgba (cr, 1, 0, 0, 1);
|
||||
cairo_set_source_rgb (cr, 1, 0, 0);
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
|
||||
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
|
||||
@@ -149,8 +172,36 @@ update_image (void)
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
for (int i = 0; i < path->num_data; i += path->data[i].header.length)
|
||||
{
|
||||
cairo_path_data_t *data = &path->data[i];
|
||||
switch (data->header.type)
|
||||
{
|
||||
case CAIRO_PATH_CURVE_TO:
|
||||
data[3].point.x *= scale; data[3].point.y *= scale;
|
||||
data[2].point.x *= scale; data[2].point.y *= scale;
|
||||
data[1].point.x *= scale; data[1].point.y *= scale;
|
||||
break;
|
||||
case CAIRO_PATH_LINE_TO:
|
||||
case CAIRO_PATH_MOVE_TO:
|
||||
data[1].point.x *= scale; data[1].point.y *= scale;
|
||||
break;
|
||||
case CAIRO_PATH_CLOSE_PATH:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
cairo_set_source_rgba (cr, 0, 0, 1, outline_alpha);
|
||||
cairo_move_to (cr, scale * 20 - 0.5, scale * 20 - 0.5);
|
||||
cairo_append_path (cr, path);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_path_destroy (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -158,10 +209,26 @@ update_image (void)
|
||||
PangoLayoutRun *run;
|
||||
PangoGlyphInfo *g;
|
||||
int i, j;
|
||||
GString *str;
|
||||
gunichar ch;
|
||||
|
||||
if (*text == '\0')
|
||||
text = " ";
|
||||
|
||||
ch = g_utf8_get_char (text);
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g_string_append_unichar (str, ch);
|
||||
g_string_append_unichar (str, 0x200c);
|
||||
}
|
||||
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, "aaaa", -1);
|
||||
pango_layout_set_text (layout, str->str, -1);
|
||||
g_string_free (str, TRUE);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
pango_extents_to_pixels (&logical, NULL);
|
||||
|
||||
@@ -176,7 +243,7 @@ update_image (void)
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[i]);
|
||||
g = &(run->glyphs->glyphs[2*i]);
|
||||
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
|
||||
}
|
||||
|
||||
@@ -184,7 +251,7 @@ update_image (void)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[i]);
|
||||
g = &(run->glyphs->glyphs[2*i]);
|
||||
g->geometry.x_offset = i * (PANGO_SCALE / 4);
|
||||
g->geometry.y_offset = j * (PANGO_SCALE / 4);
|
||||
}
|
||||
@@ -203,7 +270,6 @@ update_image (void)
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
|
||||
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
|
||||
|
||||
g_object_unref (pixbuf2);
|
||||
@@ -211,6 +277,78 @@ update_image (void)
|
||||
pango_font_description_free (desc);
|
||||
}
|
||||
|
||||
static gboolean fading = FALSE;
|
||||
static double start_pixel_alpha;
|
||||
static double end_pixel_alpha;
|
||||
static double start_outline_alpha;
|
||||
static double end_outline_alpha;
|
||||
static gint64 start_time;
|
||||
static gint64 end_time;
|
||||
|
||||
static double
|
||||
ease_out_cubic (double t)
|
||||
{
|
||||
double p = t - 1;
|
||||
return p * p * p + 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
change_alpha (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
gint64 now = g_get_monotonic_time ();
|
||||
double t;
|
||||
|
||||
t = ease_out_cubic ((now - start_time) / (double) (end_time - start_time));
|
||||
|
||||
pixel_alpha = start_pixel_alpha + (end_pixel_alpha - start_pixel_alpha) * t;
|
||||
outline_alpha = start_outline_alpha + (end_outline_alpha - start_outline_alpha) * t;
|
||||
|
||||
update_image ();
|
||||
|
||||
if (now >= end_time)
|
||||
{
|
||||
fading = FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_alpha_fade (void)
|
||||
{
|
||||
gboolean pixels;
|
||||
gboolean outlines;
|
||||
|
||||
if (fading)
|
||||
return;
|
||||
|
||||
pixels = gtk_check_button_get_active (GTK_CHECK_BUTTON (show_pixels));
|
||||
outlines = gtk_check_button_get_active (GTK_CHECK_BUTTON (show_outlines));
|
||||
|
||||
start_pixel_alpha = pixel_alpha;
|
||||
if (pixels && outlines)
|
||||
end_pixel_alpha = 0.5;
|
||||
else if (pixels)
|
||||
end_pixel_alpha = 1;
|
||||
else
|
||||
end_pixel_alpha = 0;
|
||||
|
||||
start_outline_alpha = outline_alpha;
|
||||
if (outlines)
|
||||
end_outline_alpha = 1.0;
|
||||
else
|
||||
end_outline_alpha = 0.0;
|
||||
|
||||
start_time = g_get_monotonic_time ();
|
||||
end_time = start_time + G_TIME_SPAN_SECOND / 2;
|
||||
|
||||
fading = TRUE;
|
||||
gtk_widget_add_tick_callback (window, change_alpha, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_buttons (void)
|
||||
{
|
||||
@@ -218,20 +356,26 @@ update_buttons (void)
|
||||
gtk_widget_set_sensitive (down_button, scale > 1);
|
||||
}
|
||||
|
||||
static void
|
||||
scale_up (void)
|
||||
static gboolean
|
||||
scale_up (GtkWidget *widget,
|
||||
GVariant *args,
|
||||
gpointer user_data)
|
||||
{
|
||||
scale += 1;
|
||||
update_buttons ();
|
||||
update_image ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
scale_down (void)
|
||||
static gboolean
|
||||
scale_down (GtkWidget *widget,
|
||||
GVariant *args,
|
||||
gpointer user_data)
|
||||
{
|
||||
scale -= 1;
|
||||
update_buttons ();
|
||||
update_image ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -252,20 +396,26 @@ do_fontrendering (GtkWidget *do_widget)
|
||||
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
|
||||
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
|
||||
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
|
||||
anti_alias = GTK_WIDGET (gtk_builder_get_object (builder, "antialias"));
|
||||
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
|
||||
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
|
||||
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
|
||||
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
|
||||
show_pixels = GTK_WIDGET (gtk_builder_get_object (builder, "show_pixels"));
|
||||
show_outlines = GTK_WIDGET (gtk_builder_get_object (builder, "show_outlines"));
|
||||
|
||||
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
|
||||
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
|
||||
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (anti_alias, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (show_pixels, "notify::active", G_CALLBACK (start_alpha_fade), NULL);
|
||||
g_signal_connect (show_outlines, "notify::active", G_CALLBACK (start_alpha_fade), NULL);
|
||||
|
||||
update_image ();
|
||||
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="scale_adj">
|
||||
<property name="upper">24</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">4</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">1080</property>
|
||||
<property name="default-height">430</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child type="title">
|
||||
@@ -87,35 +82,62 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hinting</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<object class="GtkCheckButton" id="show_pixels">
|
||||
<property name="label">Show _Pixels</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
<property name="column">3</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<property name="valign">center</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
<object class="GtkCheckButton" id="show_outlines">
|
||||
<property name="label">Show _Outline</property>
|
||||
<property name="use-underline">1</property>
|
||||
<layout>
|
||||
<property name="column">3</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">_Hinting</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="mnemonic-widget">hinting</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<property name="valign">center</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="hint_metrics">
|
||||
<property name="label">Hint Metrics</property>
|
||||
<object class="GtkCheckButton" id="antialias">
|
||||
<property name="label">_Antialias</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
<property name="row">1</property>
|
||||
@@ -123,21 +145,31 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_extents">
|
||||
<property name="label">Show Extents</property>
|
||||
<property name="active">1</property>
|
||||
<object class="GtkCheckButton" id="hint_metrics">
|
||||
<property name="label">Hint _Metrics</property>
|
||||
<property name="use-underline">1</property>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_extents">
|
||||
<property name="label">Show _Extents</property>
|
||||
<property name="use-underline">1</property>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_grid">
|
||||
<property name="active">1</property>
|
||||
<property name="label">Show Grid</property>
|
||||
<property name="label">Show _Grid</property>
|
||||
<property name="use-underline">1</property>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="column">6</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
@@ -148,8 +180,19 @@
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkShortcutController">
|
||||
<property name="scope">managed</property>
|
||||
<child>
|
||||
<object class="GtkShortcut">
|
||||
<property name="trigger"><Control>plus</property>
|
||||
<property name="action">activate</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
<property name="column">7</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
@@ -160,8 +203,19 @@
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkShortcutController">
|
||||
<property name="scope">managed</property>
|
||||
<child>
|
||||
<object class="GtkShortcut">
|
||||
<property name="trigger"><Control>minus</property>
|
||||
<property name="action">activate</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
<property name="column">7</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
@@ -170,7 +224,7 @@
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">7</property>
|
||||
<property name="column">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
+49
-22
@@ -61,12 +61,26 @@ show_page (GtkTextView *text_view,
|
||||
int page)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
GtkTextIter iter, start;
|
||||
GtkTextMark *mark;
|
||||
GtkWidget *child;
|
||||
GtkTextChildAnchor *anchor;
|
||||
GtkEventController *controller;
|
||||
GtkTextTag *bold, *mono, *nobreaks;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
|
||||
bold = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"scale", PANGO_SCALE_X_LARGE,
|
||||
NULL);
|
||||
mono = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"family", "monospace",
|
||||
NULL);
|
||||
nobreaks = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"allow-breaks", FALSE,
|
||||
NULL);
|
||||
|
||||
gtk_text_buffer_set_text (buffer, "", 0);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
@@ -104,17 +118,22 @@ show_page (GtkTextView *text_view,
|
||||
}
|
||||
else if (page == 2)
|
||||
{
|
||||
GtkTextTag *tag;
|
||||
mark = gtk_text_buffer_create_mark (buffer, "mark", &iter, TRUE);
|
||||
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"scale", PANGO_SCALE_X_LARGE,
|
||||
NULL);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, "tag", -1, tag, NULL);
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"family", "monospace",
|
||||
NULL);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, " / tag / ", -1, tag, NULL);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, "tag", -1, bold, NULL);
|
||||
gtk_text_buffer_insert (buffer, &iter, " /", -1);
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
|
||||
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
|
||||
gtk_text_buffer_insert (buffer, &iter, " ", -1);
|
||||
|
||||
gtk_text_buffer_move_mark (buffer, mark, &iter);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, "tag", -1, mono, NULL);
|
||||
gtk_text_buffer_insert (buffer, &iter, " /", -1);
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
|
||||
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
|
||||
gtk_text_buffer_insert (buffer, &iter, " ", -1);
|
||||
|
||||
anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
|
||||
child = gtk_image_new_from_icon_name ("audio-volume-high-symbolic");
|
||||
@@ -132,20 +151,26 @@ show_page (GtkTextView *text_view,
|
||||
"behavior of mouse and key presses, “lock” a range of text so the "
|
||||
"user can't edit it, or countless other things.\n", -1);
|
||||
insert_link (buffer, &iter, "Go back", 1);
|
||||
|
||||
gtk_text_buffer_delete_mark (buffer, mark);
|
||||
}
|
||||
else if (page == 3)
|
||||
{
|
||||
GtkTextTag *tag;
|
||||
mark = gtk_text_buffer_create_mark (buffer, "mark", &iter, TRUE);
|
||||
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"scale", PANGO_SCALE_X_LARGE,
|
||||
NULL);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, "hypertext", -1, tag, NULL);
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"family", "monospace",
|
||||
NULL);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, " / ˈhaɪ pərˌtɛkst / ", -1, tag, NULL);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, "hypertext", -1, bold, NULL);
|
||||
gtk_text_buffer_insert (buffer, &iter, " /", -1);
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
|
||||
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
|
||||
gtk_text_buffer_insert (buffer, &iter, " ", -1);
|
||||
|
||||
gtk_text_buffer_move_mark (buffer, mark, &iter);
|
||||
gtk_text_buffer_insert_with_tags (buffer, &iter, "ˈhaɪ pərˌtɛkst", -1, mono, NULL);
|
||||
gtk_text_buffer_insert (buffer, &iter, " /", -1);
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
|
||||
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
|
||||
gtk_text_buffer_insert (buffer, &iter, " ", -1);
|
||||
|
||||
anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
|
||||
child = gtk_image_new_from_icon_name ("audio-volume-high-symbolic");
|
||||
@@ -159,6 +184,8 @@ show_page (GtkTextView *text_view,
|
||||
"Machine-readable text that is not sequential but is organized "
|
||||
"so that related items of information are connected.\n", -1);
|
||||
insert_link (buffer, &iter, "Go back", 1);
|
||||
|
||||
gtk_text_buffer_delete_mark (buffer, mark);
|
||||
}
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
}
|
||||
@@ -358,7 +385,7 @@ do_hypertext (GtkWidget *do_widget)
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), view);
|
||||
|
||||
@@ -58,7 +58,7 @@ do_markup (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 450, 450);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 680);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
stack = gtk_stack_new ();
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
|
||||
Text sizes: <span size="xx-small">tiny</span> <span size="x-small">very small</span> <span size="small">small</span> <span size="medium">normal</span> <span size="large">large</span> <span size="x-large">very large</span> <span size="xx-large">huge</span>
|
||||
Text sizes: <span size="xx-small">tiny </span><span size="x-small">very small </span><span size="small">small </span><span size="medium">normal </span><span size="large">large </span><span size="x-large">very large </span><span size="xx-large">huge</span>
|
||||
|
||||
Text styles: <span style="normal">Normal</span> <span style="italic">Italic</span> <span style="oblique">Olique</span>
|
||||
|
||||
Text weights: <span weight="thin">thin</span> <span weight="light">light</span> <span weight="normal">normal</span> <span weight="bold">bold</span> <span weight="ultraheavy">ultraheavy</span>
|
||||
|
||||
Text <span color="gray">c<span color="green">o</span>l<span color="tomato">o</span>rs</span> and <span background="pink">backgrounds</span>
|
||||
|
||||
@@ -15,6 +19,12 @@ OpenType font features: <span font_desc="sans regular" font_features="dlig=0">fe
|
||||
|
||||
Shortcuts: <tt>Monospace</tt> – <b>Bold</b> – <i>Italic</i> – <big>Big</big> – <small>Small</small> – <u>Underlined</u> – <s>Strikethrough</s> – Super<sup>script</sup> – Sub<sub>script</sub>
|
||||
|
||||
<span allow_breaks="false">A</span> hyphenation algorithm is a set of rules, especially one codified for implementation in a computer program, that decides at which points a word can be broken over two lines with a hyphen. For example, a hyphenation algorithm might decide that impeachment can be broken as <span allow_breaks="false">impeach‧ment</span> or <span allow_breaks="false">im‧peachment</span> but not <span allow_breaks="false">impe‧achment.</span>
|
||||
hyphenation algorithm is a <span allow_breaks="false" style="italic">set of rules</span>, especially one codified for implementation in a computer program, that decides at which points a word can be broken over two lines with a hyphen. For example, a hyphenation algorithm might decide that impeachment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
|
||||
|
||||
<span insert_hyphens="false">one/two three/four five/six seven/eight nine/ten</span>
|
||||
|
||||
<span line_height='1.33'>Line height: This is an example of widely spaced text. It was achieved by setting the line-height factor to 1.33. You can set the line-height factor to any value between 0 and 10.
|
||||
Note that the line height affects the spacing between paragraphs as well as between the wrapped lines inside a paragraph.</span>
|
||||
|
||||
Transforms: <span text_transform='uppercase'>straße</span> <span text_transform='capitalize'>up, up and away</span>
|
||||
|
||||
|
||||
+15
-1
@@ -21,8 +21,10 @@ do_menu (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *scale;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
||||
@@ -31,11 +33,23 @@ do_menu (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), sw);
|
||||
|
||||
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||
gtk_box_append (GTK_BOX (box), scale);
|
||||
|
||||
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -67,6 +67,7 @@ demos = files([
|
||||
'paintable_animated.c',
|
||||
'paintable_emblem.c',
|
||||
'paintable_mediastream.c',
|
||||
'paintable_symbolic.c',
|
||||
'panes.c',
|
||||
'password_entry.c',
|
||||
'peg_solitaire.c',
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.Demo4.desktop</id>
|
||||
<id>org.gtk.Demo4</id>
|
||||
<launchable type="desktop-id">org.gtk.Demo4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Demo</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<description>
|
||||
@@ -30,6 +31,7 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||
<description>
|
||||
|
||||
+13
-11
@@ -45,26 +45,27 @@ struct _GtkNuclearIconClass
|
||||
* so that it can be called from all the other demos, too.
|
||||
*/
|
||||
void
|
||||
gtk_nuclear_snapshot (GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height,
|
||||
double rotation,
|
||||
gboolean draw_background)
|
||||
gtk_nuclear_snapshot (GtkSnapshot *snapshot,
|
||||
const GdkRGBA *foreground,
|
||||
const GdkRGBA *background,
|
||||
double width,
|
||||
double height,
|
||||
double rotation)
|
||||
{
|
||||
#define RADIUS 0.3
|
||||
cairo_t *cr;
|
||||
double size;
|
||||
|
||||
if (draw_background)
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 },
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
background,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
size = MIN (width, height);
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT ((width - size) / 2.0,
|
||||
(height - size) / 2.0,
|
||||
size, size));
|
||||
gdk_cairo_set_source_rgba (cr, foreground);
|
||||
cairo_translate (cr, width / 2.0, height / 2.0);
|
||||
cairo_scale (cr, size, size);
|
||||
cairo_rotate (cr, rotation);
|
||||
@@ -94,9 +95,10 @@ gtk_nuclear_icon_snapshot (GdkPaintable *paintable,
|
||||
*/
|
||||
|
||||
gtk_nuclear_snapshot (snapshot,
|
||||
&(GdkRGBA) { 0, 0, 0, 1 }, /* black */
|
||||
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 }, /* yellow */
|
||||
width, height,
|
||||
nuclear->rotation,
|
||||
TRUE);
|
||||
nuclear->rotation);
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
void gtk_nuclear_snapshot (GtkSnapshot *snapshot,
|
||||
const GdkRGBA *foreground,
|
||||
const GdkRGBA *background,
|
||||
double width,
|
||||
double height,
|
||||
double rotation,
|
||||
gboolean draw_background);
|
||||
double rotation);
|
||||
|
||||
GdkPaintable * gtk_nuclear_icon_new (double rotation);
|
||||
GdkPaintable * gtk_nuclear_animation_new (gboolean draw_background);
|
||||
|
||||
@@ -65,9 +65,12 @@ gtk_nuclear_animation_snapshot (GdkPaintable *paintable,
|
||||
|
||||
/* We call the function from the previous example here. */
|
||||
gtk_nuclear_snapshot (snapshot,
|
||||
&(GdkRGBA) { 0, 0, 0, 1 }, /* black */
|
||||
nuclear->draw_background
|
||||
? &(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 } /* yellow */
|
||||
: &(GdkRGBA) { 0, 0, 0, 0 }, /* transparent */
|
||||
width, height,
|
||||
2 * G_PI * nuclear->progress / MAX_PROGRESS,
|
||||
nuclear->draw_background);
|
||||
2 * G_PI * nuclear->progress / MAX_PROGRESS);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
|
||||
@@ -73,9 +73,10 @@ gtk_nuclear_media_stream_snapshot (GdkPaintable *paintable,
|
||||
|
||||
/* We call the function from the previous example here. */
|
||||
gtk_nuclear_snapshot (snapshot,
|
||||
&(GdkRGBA) { 0, 0, 0, 1 }, /* black */
|
||||
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 }, /* yellow */
|
||||
width, height,
|
||||
2 * G_PI * nuclear->progress / DURATION,
|
||||
TRUE);
|
||||
2 * G_PI * nuclear->progress / DURATION);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/* Paintable/Symbolic Paintable
|
||||
*
|
||||
* GdkPaintables can be made to follow the theme's colors. GTK calls
|
||||
* icons that do this symbolic icons, paintables that want to have
|
||||
* the same effect can implement the GtkSymbolicPaintable interface.
|
||||
*
|
||||
* We will adapt the original paintable example by adding the ability
|
||||
* to recolor the paintable based on the symbolic colors.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "paintable.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
/* First, add the boilerplate for the object itself.
|
||||
* This part would normally go in the header.
|
||||
*/
|
||||
#define GTK_TYPE_NUCLEAR_SYMBOLIC (gtk_nuclear_symbolic_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkNuclearSymbolic, gtk_nuclear_symbolic, GTK, NUCLEAR_SYMBOLIC, GObject)
|
||||
|
||||
/* Declare a few warning levels, so we can pick colors based on them */
|
||||
typedef enum
|
||||
{
|
||||
WARNING_NONE,
|
||||
WARNING_ALERT,
|
||||
WARNING_EMERGENCY
|
||||
} WarningLevel;
|
||||
|
||||
/* Declare the struct. */
|
||||
struct _GtkNuclearSymbolic
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
WarningLevel warning_level;
|
||||
};
|
||||
|
||||
struct _GtkNuclearSymbolicClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* Add a function to draw the nuclear icon in the given colors */
|
||||
static void
|
||||
gtk_nuclear_symbolic_snapshot_symbolic (GtkSymbolicPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height,
|
||||
const GdkRGBA *colors,
|
||||
gsize n_colors)
|
||||
{
|
||||
GtkNuclearSymbolic *self = GTK_NUCLEAR_SYMBOLIC (paintable);
|
||||
static const GdkRGBA transparent = { 0, };
|
||||
const GdkRGBA *bg_color;
|
||||
|
||||
/* select the right background color from the warning level */
|
||||
switch (self->warning_level)
|
||||
{
|
||||
case WARNING_NONE:
|
||||
bg_color = &transparent;
|
||||
break;
|
||||
case WARNING_ALERT:
|
||||
bg_color = &colors[GTK_SYMBOLIC_COLOR_WARNING];
|
||||
break;
|
||||
case WARNING_EMERGENCY:
|
||||
bg_color = &colors[GTK_SYMBOLIC_COLOR_ERROR];
|
||||
break;
|
||||
default:
|
||||
/* This should never happen, but we better do defensive coding
|
||||
* with this critical icon */
|
||||
g_assert_not_reached ();
|
||||
bg_color = &transparent;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Draw the icon with the selected warning color */
|
||||
gtk_nuclear_snapshot (snapshot,
|
||||
&colors[GTK_SYMBOLIC_COLOR_FOREGROUND],
|
||||
bg_color,
|
||||
width, height,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_nuclear_symbolic_symbolic_paintable_init (GtkSymbolicPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot_symbolic = gtk_nuclear_symbolic_snapshot_symbolic;
|
||||
}
|
||||
|
||||
/* We need to implement the functionality required by the GdkPaintable interface */
|
||||
static void
|
||||
gtk_nuclear_symbolic_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
/* Calling this function without passing a color is a neat trick
|
||||
* to make GTK use default colors and otherwise forward the call
|
||||
* to the snapshotting function above.
|
||||
*/
|
||||
gtk_symbolic_paintable_snapshot_symbolic (GTK_SYMBOLIC_PAINTABLE (paintable),
|
||||
snapshot,
|
||||
width, height,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
gtk_nuclear_symbolic_get_flags (GdkPaintable *paintable)
|
||||
{
|
||||
/* This image has a static size, but the contents may change:
|
||||
* We draw different things when the warning level changes.
|
||||
*/
|
||||
return GDK_PAINTABLE_STATIC_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_nuclear_symbolic_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = gtk_nuclear_symbolic_snapshot;
|
||||
iface->get_flags = gtk_nuclear_symbolic_get_flags;
|
||||
}
|
||||
|
||||
/* When defining the GType, we need to implement bot the GdkPaintable
|
||||
* and the GtkSymbolicPaintable interface */
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkNuclearSymbolic, gtk_nuclear_symbolic, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_nuclear_symbolic_paintable_init)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_SYMBOLIC_PAINTABLE,
|
||||
gtk_nuclear_symbolic_symbolic_paintable_init))
|
||||
|
||||
static void
|
||||
gtk_nuclear_symbolic_class_init (GtkNuclearSymbolicClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_nuclear_symbolic_init (GtkNuclearSymbolic *nuclear)
|
||||
{
|
||||
}
|
||||
|
||||
/* And finally, we add the simple constructor we declared in the header. */
|
||||
GdkPaintable *
|
||||
gtk_nuclear_symbolic_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_NUCLEAR_SYMBOLIC, NULL);
|
||||
}
|
||||
|
||||
/* Add some fun feature to the button */
|
||||
static void
|
||||
nuclear_button_clicked (GtkButton *button,
|
||||
GtkNuclearSymbolic *nuclear)
|
||||
{
|
||||
if (nuclear->warning_level >= WARNING_EMERGENCY)
|
||||
{
|
||||
/* On maximum warning level, reset the warning */
|
||||
nuclear->warning_level = WARNING_NONE;
|
||||
/* And sometimes (but not always to confuse people)
|
||||
* close the window.
|
||||
*/
|
||||
if (g_random_boolean ())
|
||||
gtk_window_close (GTK_WINDOW (window));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise just increase the warning level */
|
||||
nuclear->warning_level++;
|
||||
}
|
||||
|
||||
/* Don't forget to emit the signal causing the paintable to redraw.
|
||||
* Changing the warning level changes the background color after all.
|
||||
*/
|
||||
gdk_paintable_invalidate_contents (GDK_PAINTABLE (nuclear));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_paintable_symbolic (GtkWidget *do_widget)
|
||||
{
|
||||
GdkPaintable *nuclear;
|
||||
GtkWidget *image, *button;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Don't click!");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
button = gtk_button_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), button);
|
||||
|
||||
nuclear = gtk_nuclear_symbolic_new ();
|
||||
image = gtk_image_new_from_paintable (nuclear);
|
||||
|
||||
gtk_button_set_child (GTK_BUTTON (button), image);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (nuclear_button_clicked), nuclear);
|
||||
g_object_unref (nuclear);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.IconBrowser4.desktop</id>
|
||||
<id>org.gtk.IconBrowser4</id>
|
||||
<launchable type="desktop-id">org.gtk.IconBrowser4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Icon Browser</name>
|
||||
<summary>Program to browse themed icons</summary>
|
||||
<description>
|
||||
@@ -29,6 +30,7 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||
<description>
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "gtkrendererpaintableprivate.h"
|
||||
|
||||
#include "gsk/gskrendernodeparserprivate.h"
|
||||
#include "gsk/gl/gskglrenderer.h"
|
||||
#include "gsk/ngl/gsknglrenderer.h"
|
||||
#ifdef GDK_WINDOWING_BROADWAY
|
||||
#include "gsk/broadway/gskbroadwayrenderer.h"
|
||||
@@ -61,7 +60,7 @@ struct _NodeEditorWindow
|
||||
|
||||
GtkWidget *renderer_listbox;
|
||||
GListStore *renderers;
|
||||
GdkPaintable *paintable;
|
||||
GskRenderNode *node;
|
||||
|
||||
GFileMonitor *file_monitor;
|
||||
|
||||
@@ -168,7 +167,6 @@ static void
|
||||
text_changed (GtkTextBuffer *buffer,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
char *text;
|
||||
GBytes *bytes;
|
||||
GtkTextIter iter;
|
||||
@@ -179,10 +177,12 @@ text_changed (GtkTextBuffer *buffer,
|
||||
text_buffer_remove_all_tags (self->text_buffer);
|
||||
bytes = g_bytes_new_take (text, strlen (text));
|
||||
|
||||
g_clear_pointer (&self->node, gsk_render_node_unref);
|
||||
|
||||
/* If this is too slow, go fix the parser performance */
|
||||
node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
|
||||
self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
|
||||
g_bytes_unref (bytes);
|
||||
if (node)
|
||||
if (self->node)
|
||||
{
|
||||
/* XXX: Is this code necessary or can we have API to turn nodes into paintables? */
|
||||
GtkSnapshot *snapshot;
|
||||
@@ -191,10 +191,9 @@ text_changed (GtkTextBuffer *buffer,
|
||||
guint i;
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
gsk_render_node_get_bounds (self->node, &bounds);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- bounds.origin.x, - bounds.origin.y));
|
||||
gtk_snapshot_append_node (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
gtk_snapshot_append_node (snapshot, self->node);
|
||||
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (self->picture), paintable);
|
||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i++)
|
||||
@@ -338,15 +337,9 @@ text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_file_contents (NodeEditorWindow *self,
|
||||
GFile *file)
|
||||
load_bytes (NodeEditorWindow *self,
|
||||
GBytes *bytes)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, NULL);
|
||||
if (bytes == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
|
||||
{
|
||||
g_bytes_unref (bytes);
|
||||
@@ -362,6 +355,105 @@ load_file_contents (NodeEditorWindow *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_file_contents (NodeEditorWindow *self,
|
||||
GFile *file)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, NULL);
|
||||
if (bytes == NULL)
|
||||
return FALSE;
|
||||
|
||||
return load_bytes (self, bytes);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
on_picture_drag_prepare_cb (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
if (self->node == NULL)
|
||||
return NULL;
|
||||
|
||||
return gdk_content_provider_new_typed (GSK_TYPE_RENDER_NODE, self->node);
|
||||
}
|
||||
|
||||
static void
|
||||
on_picture_drop_read_done_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
NodeEditorWindow *self = data;
|
||||
GOutputStream *stream = G_OUTPUT_STREAM (source);
|
||||
GdkDrop *drop = g_object_get_data (source, "drop");
|
||||
GdkDragAction action = 0;
|
||||
GBytes *bytes;
|
||||
|
||||
if (g_output_stream_splice_finish (stream, res, NULL) >= 0)
|
||||
{
|
||||
bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (stream));
|
||||
if (load_bytes (self, bytes))
|
||||
action = GDK_ACTION_COPY;
|
||||
}
|
||||
|
||||
g_object_unref (self);
|
||||
gdk_drop_finish (drop, action);
|
||||
g_object_unref (drop);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
on_picture_drop_read_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
NodeEditorWindow *self = data;
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
GInputStream *input;
|
||||
GOutputStream *output;
|
||||
|
||||
input = gdk_drop_read_finish (drop, res, NULL, NULL);
|
||||
if (input == NULL)
|
||||
{
|
||||
g_object_unref (self);
|
||||
gdk_drop_finish (drop, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
output = g_memory_output_stream_new_resizable ();
|
||||
g_object_set_data (G_OBJECT (output), "drop", drop);
|
||||
g_object_ref (drop);
|
||||
|
||||
g_output_stream_splice_async (output,
|
||||
input,
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
on_picture_drop_read_done_cb,
|
||||
self);
|
||||
g_object_unref (output);
|
||||
g_object_unref (input);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_picture_drop_cb (GtkDropTargetAsync *dest,
|
||||
GdkDrop *drop,
|
||||
double x,
|
||||
double y,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
gdk_drop_read_async (drop,
|
||||
(const char *[2]) { "application/x-gtk-render-node", NULL },
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
on_picture_drop_read_cb,
|
||||
g_object_ref (self));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
file_changed_cb (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
@@ -736,6 +828,7 @@ node_editor_window_finalize (GObject *object)
|
||||
|
||||
g_array_free (self->errors, TRUE);
|
||||
|
||||
g_clear_pointer (&self->node, gsk_render_node_unref);
|
||||
g_clear_object (&self->renderers);
|
||||
|
||||
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
|
||||
@@ -778,12 +871,9 @@ node_editor_window_realize (GtkWidget *widget)
|
||||
NULL,
|
||||
"Default");
|
||||
#endif
|
||||
node_editor_window_add_renderer (self,
|
||||
gsk_gl_renderer_new (),
|
||||
"OpenGL");
|
||||
node_editor_window_add_renderer (self,
|
||||
gsk_ngl_renderer_new (),
|
||||
"NGL");
|
||||
"OpenGL");
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
node_editor_window_add_renderer (self,
|
||||
gsk_vulkan_renderer_new (),
|
||||
@@ -848,6 +938,8 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
|
||||
gtk_widget_class_bind_template_callback (widget_class, testcase_save_clicked_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, testcase_name_entry_changed_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, dark_mode_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_picture_drag_prepare_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_picture_drop_cb);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
|
||||
@@ -200,6 +200,19 @@
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTargetAsync">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">application/x-gtk-render-node</property>
|
||||
<signal name="drop" handler="on_picture_drop_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.PrintEditor4.desktop</id>
|
||||
<id>org.gtk.PrintEditor4</id>
|
||||
<launchable type="desktop-id">org.gtk.PrintEditor4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Print Editor</name>
|
||||
<summary>Program to demonstrate GTK printing</summary>
|
||||
<description>
|
||||
@@ -24,6 +25,7 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="3.99.0" date="2020-07-30">
|
||||
<description>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.WidgetFactory4.desktop</id>
|
||||
<id>org.gtk.WidgetFactory4</id>
|
||||
<launchable type="desktop-id">org.gtk.WidgetFactory4.desktop</launchable>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<project_license>LGPL-2.1-or-later</project_license>
|
||||
<name>GTK Widget Factory</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<description>
|
||||
@@ -31,6 +32,7 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="@BUILD_VERSION@" date="@BUILD_DATE@">
|
||||
<description>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 MiB |
@@ -696,6 +696,37 @@ on_range_to_changed (GtkSpinButton *to)
|
||||
gtk_spin_button_set_value (from, v2);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
on_picture_drag_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
|
||||
picture = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, gtk_picture_get_paintable (GTK_PICTURE (picture)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_picture_drop (GtkDropTarget *dest,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
picture = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
paintable = g_value_get_object (value);
|
||||
|
||||
gtk_picture_set_paintable (GTK_PICTURE (picture), paintable);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
info_bar_response (GtkWidget *infobar, int response_id)
|
||||
{
|
||||
@@ -1182,7 +1213,7 @@ populate_flowbox (GtkWidget *flowbox)
|
||||
GtkWidget *child;
|
||||
int i;
|
||||
const char *resources[] = {
|
||||
"sunset.jpg", "snowy.jpg", "portland-rose.jpg"
|
||||
"sunset.jpg", "portland-rose.jpg", "beach.jpg", "nyc.jpg"
|
||||
};
|
||||
|
||||
if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (flowbox), "populated")))
|
||||
@@ -2040,6 +2071,8 @@ activate (GApplication *app)
|
||||
"on_page_combo_changed", (GCallback)on_page_combo_changed,
|
||||
"on_range_from_changed", (GCallback)on_range_from_changed,
|
||||
"on_range_to_changed", (GCallback)on_range_to_changed,
|
||||
"on_picture_drag_prepare", (GCallback)on_picture_drag_prepare,
|
||||
"on_picture_drop", (GCallback)on_picture_drop,
|
||||
"tab_close_cb", (GCallback)tab_close_cb,
|
||||
"increase_icon_size", (GCallback)increase_icon_size,
|
||||
"decrease_icon_size", (GCallback)decrease_icon_size,
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
<gresource prefix="/org/gtk/WidgetFactory4">
|
||||
<file>gtk-logo.webm</file>
|
||||
<file>sunset.jpg</file>
|
||||
<file>snowy.jpg</file>
|
||||
<file>portland-rose.jpg</file>
|
||||
<file>nyc.jpg</file>
|
||||
<file>beach.jpg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -1051,22 +1051,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="spacing">10</property>
|
||||
<property name="hexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="valign">start</property>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="label" translatable="yes"><b>Video</b></property>
|
||||
<property name="use-markup">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
<object class="GtkVideo">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="autoplay">1</property>
|
||||
<property name="loop">1</property>
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/gtk-logo.webm</property>
|
||||
@@ -1075,66 +1062,78 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<object class="GtkFrame">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="label" translatable="yes"><b>Text Styles</b></property>
|
||||
<property name="use-markup">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">10</property>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="propagate-natural-height">1</property>
|
||||
<property name="propagate-natural-width">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Large Title</property>
|
||||
<style><class name="large-title"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 1</property>
|
||||
<style><class name="title-1"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 2</property>
|
||||
<style><class name="title-2"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 3</property>
|
||||
<style><class name="title-3"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 4</property>
|
||||
<style><class name="title-4"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Heading</property>
|
||||
<style><class name="heading"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Body</property>
|
||||
<style><class name="body"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Caption Heading</property>
|
||||
<style><class name="caption-heading"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Caption</property>
|
||||
<style><class name="caption"/></style>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Large Title</property>
|
||||
<style><class name="large-title"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 1</property>
|
||||
<style><class name="title-1"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 2</property>
|
||||
<style><class name="title-2"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 3</property>
|
||||
<style><class name="title-3"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Title 4</property>
|
||||
<style><class name="title-4"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Heading</property>
|
||||
<style><class name="heading"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Body</property>
|
||||
<style><class name="body"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Caption Heading</property>
|
||||
<style><class name="caption-heading"/></style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Caption</property>
|
||||
<style><class name="caption"/></style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -1251,8 +1250,21 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box6">
|
||||
<property name="orientation">vertical</property>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/sunset.jpg</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture</property>
|
||||
<signal name="drop" handler="on_picture_drop" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
@@ -1265,8 +1277,21 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box7">
|
||||
<property name="orientation">vertical</property>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/nyc.jpg</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture</property>
|
||||
<signal name="drop" handler="on_picture_drop" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
@@ -1278,10 +1303,22 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="position">2</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box8">
|
||||
<property name="orientation">vertical</property>
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/beach.jpg</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<property name="actions">copy</property>
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropTarget">
|
||||
<property name="actions">copy</property>
|
||||
<property name="formats">GdkTexture</property>
|
||||
<signal name="drop" handler="on_picture_drop" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="tab">
|
||||
@@ -1299,7 +1336,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box9">
|
||||
<object class="GtkBox" id="box8">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
</property>
|
||||
|
||||
@@ -13,7 +13,7 @@ devhelp = true
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://developer.gnome.org/gobject/stable"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[theme]
|
||||
name = "basic"
|
||||
|
||||
@@ -13,7 +13,7 @@ devhelp = true
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://developer.gnome.org/gobject/stable"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[theme]
|
||||
name = "basic"
|
||||
|
||||
@@ -14,7 +14,7 @@ search_index = true
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://developer.gnome.org/gobject/stable"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."cairo-1.0"]
|
||||
name = "Cairo"
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
expand_content_md_files = [
|
||||
]
|
||||
|
||||
gdk4_toml = configure_file(input: 'gdk4.toml.in', output: 'gdk4.toml', configuration: toml_conf)
|
||||
gdk4x11_toml = configure_file(input: 'gdk4-x11.toml.in', output: 'gdk4-x11.toml', configuration: toml_conf)
|
||||
gdk4wayland_toml = configure_file(input: 'gdk4-wayland.toml.in', output: 'gdk4-wayland.toml', configuration: toml_conf)
|
||||
|
||||
if get_option('gtk_doc')
|
||||
gdk4_toml = configure_file(
|
||||
input: 'gdk4.toml.in',
|
||||
output: 'gdk4.toml',
|
||||
configuration: toml_conf,
|
||||
install: true,
|
||||
install_dir: docs_dir / 'gdk4',
|
||||
)
|
||||
|
||||
custom_target('gdk4-doc',
|
||||
input: [ gdk4_toml, gdk_gir[0] ],
|
||||
output: 'gdk4',
|
||||
@@ -28,6 +32,14 @@ if get_option('gtk_doc')
|
||||
)
|
||||
|
||||
if x11_enabled
|
||||
gdk4x11_toml = configure_file(
|
||||
input: 'gdk4-x11.toml.in',
|
||||
output: 'gdk4-x11.toml',
|
||||
configuration: toml_conf,
|
||||
install: true,
|
||||
install_dir: docs_dir / 'gdk4-x11',
|
||||
)
|
||||
|
||||
custom_target('gdk4-x11-doc',
|
||||
input: [ gdk4x11_toml, gdk_x11_gir[0] ],
|
||||
output: 'gdk4-x11',
|
||||
@@ -52,6 +64,14 @@ if get_option('gtk_doc')
|
||||
endif
|
||||
|
||||
if wayland_enabled
|
||||
gdk4wayland_toml = configure_file(
|
||||
input: 'gdk4-wayland.toml.in',
|
||||
output: 'gdk4-wayland.toml',
|
||||
configuration: toml_conf,
|
||||
install: true,
|
||||
install_dir: docs_dir / 'gdk4-wayland',
|
||||
)
|
||||
|
||||
custom_target('gdk4-wayland-doc',
|
||||
input: [ gdk4wayland_toml, gdk_wayland_gir[0] ],
|
||||
output: 'gdk4-wayland',
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
|
||||
// A map between namespaces and base URLs for their online documentation
|
||||
baseURLs = [
|
||||
[ 'Gdk', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4/' ],
|
||||
[ 'GdkWayland', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4-wayland/' ],
|
||||
[ 'GdkX11', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4-x11/' ],
|
||||
[ 'Gsk', 'https://gnome.pages.gitlab.gnome.org/gtk/gsk4/' ],
|
||||
[ 'Gtk', 'https://gnome.pages.gitlab.gnome.org/gtk/gtk4/' ],
|
||||
[ 'Pango', 'https://gnome.pages/gitlab.gnome.org/pango/pango/' ],
|
||||
[ 'PangoCairo', 'https://gnome.pages.gitlab.gnome.org/pango/pangocairo/' ],
|
||||
[ 'GLib', 'https://docs.gtk.org/glib/' ],
|
||||
[ 'GObject', 'https://docs.gtk.org/gobject/' ],
|
||||
[ 'Gio', 'https://docs.gtk.org/gio/' ],
|
||||
[ 'Gdk', 'https://docs.gtk.org/gdk4/' ],
|
||||
[ 'GdkWayland', 'https://docs.gtk.org/gdk4-wayland/' ],
|
||||
[ 'GdkX11', 'https://docs.gtk.org/gdk4-x11/' ],
|
||||
[ 'Gsk', 'https://docs.gtk.org/gsk4/' ],
|
||||
[ 'Gtk', 'https://docs.gtk.org/gtk4/' ],
|
||||
[ 'Pango', 'https://docs.gtk.org/Pango/' ],
|
||||
[ 'PangoCairo', 'https://docs.gtk.org/PangoCairo/' ],
|
||||
]
|
||||
|
||||
@@ -14,7 +14,7 @@ search_index = true
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://developer.gnome.org/gobject/stable/"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."Graphene-1.0"]
|
||||
name = "Graphene"
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
gsk4_toml = configure_file(input: 'gsk4.toml.in', output: 'gsk4.toml', configuration: toml_conf)
|
||||
|
||||
if get_option('gtk_doc')
|
||||
gsk4_toml = configure_file(
|
||||
input: 'gsk4.toml.in',
|
||||
output: 'gsk4.toml',
|
||||
configuration: toml_conf,
|
||||
install: true,
|
||||
install_dir: docs_dir / 'gsk4',
|
||||
)
|
||||
|
||||
custom_target('gsk4-doc',
|
||||
input: [ gsk4_toml, gsk_gir[0] ],
|
||||
output: 'gsk4',
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
|
||||
// A map between namespaces and base URLs for their online documentation
|
||||
baseURLs = [
|
||||
[ 'Gdk', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4/' ],
|
||||
[ 'GdkWayland', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4-wayland/' ],
|
||||
[ 'GdkX11', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4-x11/' ],
|
||||
[ 'Gsk', 'https://gnome.pages.gitlab.gnome.org/gtk/gsk4/' ],
|
||||
[ 'Gtk', 'https://gnome.pages.gitlab.gnome.org/gtk/gtk4/' ],
|
||||
[ 'Pango', 'https://gnome.pages/gitlab.gnome.org/pango/pango/' ],
|
||||
[ 'PangoCairo', 'https://gnome.pages.gitlab.gnome.org/pango/pangocairo/' ],
|
||||
[ 'GLib', 'https://docs.gtk.org/glib/' ],
|
||||
[ 'GObject', 'https://docs.gtk.org/gobject/' ],
|
||||
[ 'Gio', 'https://docs.gtk.org/gio/' ],
|
||||
[ 'Gdk', 'https://docs.gtk.org/gdk4/' ],
|
||||
[ 'GdkWayland', 'https://docs.gtk.org/gdk4-wayland/' ],
|
||||
[ 'GdkX11', 'https://docs.gtk.org/gdk4-x11/' ],
|
||||
[ 'Gsk', 'https://docs.gtk.org/gsk4/' ],
|
||||
[ 'Gtk', 'https://docs.gtk.org/gtk4/' ],
|
||||
[ 'Pango', 'https://docs.gtk.org/Pango/' ],
|
||||
[ 'PangoCairo', 'https://docs.gtk.org/PangoCairo/' ],
|
||||
]
|
||||
|
||||
@@ -162,6 +162,8 @@ done with
|
||||
|caret-color|[CSS Basic User Interface Level 3](https://www.w3.org/TR/css3-ui/#caret-color) | CSS allows an auto value |
|
||||
|-gtk-secondary-caret-color|[Color](https://www.w3.org/TR/css-color-3/#valuea-def-color) | used for the secondary caret in bidirectional text |
|
||||
|letter-spacing| [CSS Text Level 3](https://www.w3.org/TR/css3-text/#letter-spacing) | |
|
||||
|text-transform| [CSS Text Level 3](https://www.w3.org/TR/css-text-3/#text-transform-property) | CSS allows full-width and full-size-kana. Since 4.6 |
|
||||
|line-height| [CSS Inline Layout Level 3](https://www.w3.org/TR/css-inline-3/#line-height-property) | Since 4.6 |
|
||||
|text-decoration-line| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-line-property) | |
|
||||
|text-decoration-color| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-color-property) | |
|
||||
|text-decoration-style| [CSS Text Decoration Level 3](https://www.w3.org/TR/css-text-decor-3/#text-decoration-style-property) | CSS allows dashed and dotted |
|
||||
|
||||
@@ -14,7 +14,7 @@ search_index = true
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://developer.gnome.org/gobject/stable"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."Graphene-1.0"]
|
||||
name = "Graphene"
|
||||
|
||||
@@ -137,6 +137,14 @@ capture phase, and key bindings locally, during the target phase.
|
||||
Under the hood, all shortcuts are represented as instances of `GtkShortcut`,
|
||||
and they are managed by `GtkShortcutController`.
|
||||
|
||||
## Text input
|
||||
|
||||
When actual text input is needed (i.e. not just keyboard shortcuts),
|
||||
input method support can be added to a widget by connecting an input
|
||||
method context and listening to its `::commit` signal. To create a new
|
||||
input method context, use gtk_im_multicontext_new(), to provide it with
|
||||
input, use gtk_event_controller_key_set_im_context().
|
||||
|
||||
## Event controllers and gestures
|
||||
|
||||
Event controllers are standalone objects that can perform
|
||||
|
||||
@@ -27,9 +27,15 @@ expand_content_md_files = [
|
||||
'visual_index.md'
|
||||
]
|
||||
|
||||
gtk4_toml = configure_file(input: 'gtk4.toml.in', output: 'gtk4.toml', configuration: toml_conf)
|
||||
|
||||
if get_option('gtk_doc')
|
||||
gtk4_toml = configure_file(
|
||||
input: 'gtk4.toml.in',
|
||||
output: 'gtk4.toml',
|
||||
configuration: toml_conf,
|
||||
install: true,
|
||||
install_dir: docs_dir / 'gtk4',
|
||||
)
|
||||
|
||||
custom_target('gtk4-doc',
|
||||
input: [ gtk4_toml, gtk_gir[0] ],
|
||||
output: 'gtk4',
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
|
||||
// A map between namespaces and base URLs for their online documentation
|
||||
baseURLs = [
|
||||
[ 'Gdk', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4/' ],
|
||||
[ 'GdkWayland', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4-wayland/' ],
|
||||
[ 'GdkX11', 'https://gnome.pages.gitlab.gnome.org/gtk/gdk4-x11/' ],
|
||||
[ 'Gsk', 'https://gnome.pages.gitlab.gnome.org/gtk/gsk4/' ],
|
||||
[ 'Gtk', 'https://gnome.pages.gitlab.gnome.org/gtk/gtk4/' ],
|
||||
[ 'Pango', 'https://gnome.pages/gitlab.gnome.org/pango/pango/' ],
|
||||
[ 'PangoCairo', 'https://gnome.pages.gitlab.gnome.org/pango/pangocairo/' ],
|
||||
[ 'GLib', 'https://docs.gtk.org/glib/' ],
|
||||
[ 'GObject', 'https://docs.gtk.org/gobject/' ],
|
||||
[ 'Gio', 'https://docs.gtk.org/gio/' ],
|
||||
[ 'Gdk', 'https://docs.gtk.org/gdk4/' ],
|
||||
[ 'GdkWayland', 'https://docs.gtk.org/gdk4-wayland/' ],
|
||||
[ 'GdkX11', 'https://docs.gtk.org/gdk4-x11/' ],
|
||||
[ 'Gsk', 'https://docs.gtk.org/gsk4/' ],
|
||||
[ 'Gtk', 'https://docs.gtk.org/gtk4/' ],
|
||||
[ 'Pango', 'https://docs.gtk.org/Pango/' ],
|
||||
[ 'PangoCairo', 'https://docs.gtk.org/PangoCairo/' ],
|
||||
]
|
||||
|
||||
@@ -5,6 +5,10 @@ gidocgen = find_program('gi-docgen', required: get_option('gtk_doc'))
|
||||
|
||||
docs_dir = gtk_datadir / 'doc'
|
||||
|
||||
if get_option('gtk_doc') and not build_gir
|
||||
error('API reference requires introspection.')
|
||||
endif
|
||||
|
||||
subdir('gdk')
|
||||
subdir('gsk')
|
||||
subdir('gtk')
|
||||
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env -S GI_TYPELIB_PATH=${PWD}/build/gtk:${GI_TYPELIB_PATH} LD_PRELOAD=${LD_PRELOAD}:${PWD}/build/gtk/libgtk-4.so gjs
|
||||
|
||||
imports.gi.versions['Gtk'] = '4.0';
|
||||
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
|
||||
const DemoWidget = GObject.registerClass({
|
||||
GTypeName: 'DemoWidget',
|
||||
}, class DemoWidget extends Gtk.Widget {
|
||||
|
||||
_init(params = {}) {
|
||||
super._init(params);
|
||||
|
||||
let layout_manager = new Gtk.GridLayout ();
|
||||
this.set_layout_manager (layout_manager);
|
||||
this.label1 = new Gtk.Label({ label: "Red",
|
||||
hexpand: true,
|
||||
vexpand: true });
|
||||
this.label1.set_parent (this);
|
||||
let child1 = layout_manager.get_layout_child (this.label1);
|
||||
child1.set_row (0);
|
||||
child1.set_column (0);
|
||||
|
||||
this.label2 = new Gtk.Label({ label: "Green",
|
||||
hexpand: true,
|
||||
vexpand: true });
|
||||
this.label2.set_parent (this);
|
||||
let child2 = layout_manager.get_layout_child (this.label2);
|
||||
child2.set_row (0);
|
||||
child2.set_column (1);
|
||||
}
|
||||
});
|
||||
|
||||
// Create a new application
|
||||
let app = new Gtk.Application({ application_id: 'org.gtk.exampleapp' });
|
||||
|
||||
// When the application is launched…
|
||||
app.connect('activate', () => {
|
||||
// … create a new window …
|
||||
let win = new Gtk.ApplicationWindow({ application: app });
|
||||
// … with a button in it …
|
||||
let widget = new DemoWidget();
|
||||
win.set_child(widget);
|
||||
win.present();
|
||||
});
|
||||
|
||||
// Run the application
|
||||
app.run([]);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gprintf.h>
|
||||
@@ -463,7 +464,7 @@ gdk_broadway_display_flush_in_idle (GdkDisplay *display)
|
||||
if (broadway_display->idle_flush_id == 0)
|
||||
{
|
||||
broadway_display->idle_flush_id = g_idle_add (flush_idle, g_object_ref (display));
|
||||
g_source_set_name_by_id (broadway_display->idle_flush_id, "[gtk] flush_idle");
|
||||
gdk_source_set_static_name_by_id (broadway_display->idle_flush_id, "[gtk] flush_idle");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,4 +57,11 @@ guint gdk_parse_debug_var (const char *variable,
|
||||
# define g_memdup2(mem,size) g_memdup((mem),(size))
|
||||
#endif
|
||||
|
||||
void gdk_source_set_static_name_by_id (guint tag,
|
||||
const char *name);
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 69, 1)
|
||||
#define g_source_set_static_name(source, name) g_source_set_name ((source), (name))
|
||||
#endif
|
||||
|
||||
#endif /* __GDK__PRIVATE_H__ */
|
||||
|
||||
@@ -127,10 +127,12 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context" },
|
||||
{ "gl-gles", GDK_DEBUG_GL_GLES, "Use a GLES OpenGL context" },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
|
||||
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows" },
|
||||
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11" },
|
||||
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows" },
|
||||
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
|
||||
};
|
||||
|
||||
|
||||
@@ -412,3 +414,17 @@ gdk_find_base_dir (const char *text,
|
||||
return dir;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_source_set_static_name_by_id (guint tag,
|
||||
const char *name)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
g_return_if_fail (tag > 0);
|
||||
|
||||
source = g_main_context_find_source_by_id (NULL, tag);
|
||||
if (source == NULL)
|
||||
return;
|
||||
|
||||
g_source_set_static_name (source, name);
|
||||
}
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ cairo_region_t *
|
||||
gdk_cairo_region_create_from_surface
|
||||
(cairo_surface_t *surface);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_6_FOR(gdk_gl_texture_new)
|
||||
void gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
GdkSurface *surface,
|
||||
int source,
|
||||
|
||||
+8
-2
@@ -635,7 +635,7 @@ gdk_clipboard_read_internal (GdkClipboard *clipboard,
|
||||
/**
|
||||
* gdk_clipboard_read_async:
|
||||
* @clipboard: a `GdkClipboard`
|
||||
* @mime_types: a %NULL-terminated array of mime types to choose from
|
||||
* @mime_types: (array zero-terminated=1): a %NULL-terminated array of mime types to choose from
|
||||
* @io_priority: the I/O priority of the request
|
||||
* @cancellable: (nullable): optional `GCancellable` object
|
||||
* @callback: (scope async): callback to call when the request is satisfied
|
||||
@@ -1253,9 +1253,15 @@ gdk_clipboard_set_content (GdkClipboard *clipboard,
|
||||
* @...: value contents conforming to @type
|
||||
*
|
||||
* Sets the clipboard to contain the value collected from the given varargs.
|
||||
*
|
||||
* Values should be passed the same way they are passed to other value
|
||||
* collecting APIs, such as [`method@GObject.Object.set`] or
|
||||
* [`id@g_signal_emit`].
|
||||
*
|
||||
* ```c
|
||||
* gdk_clipboard_set (clipboard, GTK_TYPE_TEXT_BUFFER, buffer);
|
||||
* gdk_clipboard_set (clipboard, GTK_TYPE_STRING, "Hello World");
|
||||
*
|
||||
* gdk_clipboard_set (clipboard, GDK_TYPE_TEXTURE, some_texture);
|
||||
* ```
|
||||
*/
|
||||
void
|
||||
|
||||
+124
-18
@@ -25,6 +25,8 @@
|
||||
#include "filetransferportalprivate.h"
|
||||
#include "gdktexture.h"
|
||||
#include "gdkrgbaprivate.h"
|
||||
#include "loaders/gdkpngprivate.h"
|
||||
#include "loaders/gdktiffprivate.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
@@ -553,6 +555,8 @@ gdk_content_deserialize_async (GInputStream *stream,
|
||||
Deserializer *deserializer;
|
||||
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
g_return_if_fail (mime_type != NULL);
|
||||
g_return_if_fail (G_TYPE_IS_VALUE_TYPE (type));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
@@ -591,7 +595,10 @@ gdk_content_deserialize_finish (GAsyncResult *result,
|
||||
g_return_val_if_fail (GDK_IS_CONTENT_DESERIALIZER (result), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
deserializer = GDK_CONTENT_DESERIALIZER (result);
|
||||
g_return_val_if_fail (G_VALUE_HOLDS (value, G_VALUE_TYPE (&deserializer->value)), FALSE);
|
||||
if (G_VALUE_TYPE (value) == 0)
|
||||
g_value_init (value, G_VALUE_TYPE (&deserializer->value));
|
||||
else
|
||||
g_return_val_if_fail (G_VALUE_HOLDS (value, G_VALUE_TYPE (&deserializer->value)), FALSE);
|
||||
|
||||
if (deserializer->error)
|
||||
{
|
||||
@@ -650,6 +657,88 @@ pixbuf_deserializer (GdkContentDeserializer *deserializer)
|
||||
deserializer);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_deserializer_finish (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GdkContentDeserializer *deserializer = GDK_CONTENT_DESERIALIZER (source);
|
||||
GdkTexture *texture;
|
||||
GValue *value;
|
||||
GError *error = NULL;
|
||||
|
||||
texture = g_task_propagate_pointer (G_TASK (res), &error);
|
||||
if (texture == NULL)
|
||||
{
|
||||
gdk_content_deserializer_return_error (deserializer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
value = gdk_content_deserializer_get_value (deserializer);
|
||||
g_value_take_object (value, texture);
|
||||
gdk_content_deserializer_return_success (deserializer);
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
read_all_data (GInputStream *source,
|
||||
GError **error)
|
||||
{
|
||||
GOutputStream *output;
|
||||
gssize size;
|
||||
GBytes *bytes;
|
||||
|
||||
output = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
|
||||
size = g_output_stream_splice (output, source, 0, NULL, error);
|
||||
if (size == -1)
|
||||
{
|
||||
g_object_unref (output);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_output_stream_close (output, NULL, NULL);
|
||||
bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (output));
|
||||
g_object_unref (output);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static void
|
||||
deserialize_texture_in_thread (GTask *task,
|
||||
gpointer source_object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GdkContentDeserializer *deserializer = source_object;
|
||||
GBytes *bytes;
|
||||
GError *error = NULL;
|
||||
GdkTexture *texture = NULL;
|
||||
|
||||
bytes = read_all_data (gdk_content_deserializer_get_input_stream (deserializer), &error);
|
||||
if (bytes)
|
||||
{
|
||||
texture = gdk_texture_new_from_bytes (bytes, &error);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
if (texture)
|
||||
g_task_return_pointer (task, texture, g_object_unref);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_deserializer (GdkContentDeserializer *deserializer)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (deserializer,
|
||||
gdk_content_deserializer_get_cancellable (deserializer),
|
||||
texture_deserializer_finish,
|
||||
NULL);
|
||||
g_task_run_in_thread (task, deserialize_texture_in_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
string_deserializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@@ -858,48 +947,65 @@ init (void)
|
||||
|
||||
initialized = TRUE;
|
||||
|
||||
gdk_content_register_deserializer ("image/png",
|
||||
GDK_TYPE_TEXTURE,
|
||||
texture_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gdk_content_register_deserializer ("image/tiff",
|
||||
GDK_TYPE_TEXTURE,
|
||||
texture_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
formats = gdk_pixbuf_get_formats ();
|
||||
|
||||
/* Make sure png comes first */
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char *name;
|
||||
|
||||
char *name;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
if (g_str_equal (name, "png"))
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
|
||||
g_free (name);
|
||||
|
||||
break;
|
||||
}
|
||||
g_free (name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
}
|
||||
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char **mimes, **m;
|
||||
char *name;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
mimes = gdk_pixbuf_format_get_mime_types (fmt);
|
||||
for (m = mimes; *m; m++)
|
||||
{
|
||||
gdk_content_register_deserializer (*m,
|
||||
GDK_TYPE_TEXTURE,
|
||||
pixbuf_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
{
|
||||
/* Turning pngs and tiffs into textures is handled above */
|
||||
if (!g_str_equal (name, "png") &&
|
||||
!g_str_equal (name, "tiff"))
|
||||
gdk_content_register_deserializer (*m,
|
||||
GDK_TYPE_TEXTURE,
|
||||
pixbuf_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
gdk_content_register_deserializer (*m,
|
||||
GDK_TYPE_PIXBUF,
|
||||
pixbuf_deserializer,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
g_strfreev (mimes);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
+76
-8
@@ -179,6 +179,76 @@ gdk_content_formats_new_for_gtype (GType type)
|
||||
return gdk_content_formats_new_take (data, 1, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_content_formats_parse:
|
||||
* @string: the string to parse
|
||||
*
|
||||
* Parses the given @string into `GdkContentFormats` and
|
||||
* returns the formats.
|
||||
*
|
||||
* Strings printed via [method@Gdk.ContentFormats.to_string]
|
||||
* can be read in again successfully using this function.
|
||||
*
|
||||
* If @string does not describe valid content formats, %NULL
|
||||
* is returned.
|
||||
*
|
||||
* Returns: (nullable): the content formats if @string is valid
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
GdkContentFormats *
|
||||
gdk_content_formats_parse (const char *string)
|
||||
{
|
||||
GdkContentFormatsBuilder *builder;
|
||||
char **split;
|
||||
gsize i;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
|
||||
split = g_strsplit_set (string, "\t\n\f\r ", -1); /* same as g_ascii_isspace() */
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
|
||||
/* first the GTypes */
|
||||
for (i = 0; split[i] != NULL; i++)
|
||||
{
|
||||
GType type;
|
||||
|
||||
if (split[i][0] == 0)
|
||||
continue;
|
||||
|
||||
type = g_type_from_name (split[i]);
|
||||
if (type != 0)
|
||||
gdk_content_formats_builder_add_gtype (builder, type);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* then the mime types */
|
||||
for (; split[i] != NULL; i++)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
if (split[i][0] == 0)
|
||||
continue;
|
||||
|
||||
mime_type = gdk_intern_mime_type (split[i]);
|
||||
if (mime_type)
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (split[i] != NULL)
|
||||
{
|
||||
g_strfreev (split);
|
||||
gdk_content_formats_builder_unref (builder);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_strfreev (split);
|
||||
return gdk_content_formats_builder_free_to_formats (builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_content_formats_ref:
|
||||
* @formats: a `GdkContentFormats`
|
||||
@@ -227,10 +297,8 @@ gdk_content_formats_unref (GdkContentFormats *formats)
|
||||
*
|
||||
* Prints the given @formats into a string for human consumption.
|
||||
*
|
||||
* This is meant for debugging and logging.
|
||||
*
|
||||
* The form of the representation may change at any time and is
|
||||
* not guaranteed to stay identical.
|
||||
* The result of this function can later be parsed with
|
||||
* [func@Gdk.ContentFormats.parse].
|
||||
*/
|
||||
void
|
||||
gdk_content_formats_print (GdkContentFormats *formats,
|
||||
@@ -241,20 +309,18 @@ gdk_content_formats_print (GdkContentFormats *formats,
|
||||
g_return_if_fail (formats != NULL);
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
g_string_append (string, "{ ");
|
||||
for (i = 0; i < formats->n_gtypes; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append (string, ", ");
|
||||
g_string_append (string, " ");
|
||||
g_string_append (string, g_type_name (formats->gtypes[i]));
|
||||
}
|
||||
for (i = 0; i < formats->n_mime_types; i++)
|
||||
{
|
||||
if (i > 0 || formats->n_gtypes > 0)
|
||||
g_string_append (string, ", ");
|
||||
g_string_append (string, " ");
|
||||
g_string_append (string, formats->mime_types[i]);
|
||||
}
|
||||
g_string_append (string, " }");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,6 +329,8 @@ gdk_content_formats_print (GdkContentFormats *formats,
|
||||
*
|
||||
* Prints the given @formats into a human-readable string.
|
||||
*
|
||||
* The resulting string can be parsed with [func@Gdk.ContentFormats.parse].
|
||||
*
|
||||
* This is a small wrapper around [method@Gdk.ContentFormats.print]
|
||||
* to help when debugging.
|
||||
*
|
||||
|
||||
@@ -40,6 +40,8 @@ GdkContentFormats * gdk_content_formats_new (const char
|
||||
guint n_mime_types);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats * gdk_content_formats_new_for_gtype (GType type);
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
GdkContentFormats * gdk_content_formats_parse (const char *string);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentFormats * gdk_content_formats_ref (GdkContentFormats *formats);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -80,7 +80,7 @@ gdk_content_provider_value_get_value (GdkContentProvider *provider,
|
||||
{
|
||||
GdkContentProviderValue *content = GDK_CONTENT_PROVIDER_VALUE (provider);
|
||||
|
||||
if (G_VALUE_HOLDS (value, G_VALUE_TYPE (&content->value)))
|
||||
if (G_VALUE_HOLDS (&content->value, G_VALUE_TYPE (value)))
|
||||
{
|
||||
g_value_copy (&content->value, value);
|
||||
return TRUE;
|
||||
|
||||
+113
-18
@@ -26,6 +26,9 @@
|
||||
#include "filetransferportalprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdkrgba.h"
|
||||
#include "loaders/gdkpngprivate.h"
|
||||
#include "loaders/gdktiffprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <string.h>
|
||||
@@ -606,6 +609,7 @@ gdk_content_serialize_finish (GAsyncResult *result,
|
||||
|
||||
/*** SERIALIZERS ***/
|
||||
|
||||
|
||||
static void
|
||||
pixbuf_serializer_finish (GObject *source,
|
||||
GAsyncResult *res,
|
||||
@@ -658,6 +662,82 @@ pixbuf_serializer (GdkContentSerializer *serializer)
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_serializer_finish (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkContentSerializer *serializer = GDK_CONTENT_SERIALIZER (source);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_task_propagate_boolean (G_TASK (res), &error))
|
||||
gdk_content_serializer_return_error (serializer, error);
|
||||
else
|
||||
gdk_content_serializer_return_success (serializer);
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_texture_in_thread (GTask *task,
|
||||
gpointer source_object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GdkContentSerializer *serializer = source_object;
|
||||
const GValue *value;
|
||||
GdkTexture *texture;
|
||||
GBytes *bytes = NULL;
|
||||
GError *error = NULL;
|
||||
gboolean result = FALSE;
|
||||
|
||||
value = gdk_content_serializer_get_value (serializer);
|
||||
texture = g_value_get_object (value);
|
||||
|
||||
if (strcmp (gdk_content_serializer_get_mime_type (serializer), "image/png") == 0)
|
||||
bytes = gdk_save_png (texture);
|
||||
else if (strcmp (gdk_content_serializer_get_mime_type (serializer), "image/tiff") == 0)
|
||||
bytes = gdk_save_tiff (texture);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
if (bytes)
|
||||
{
|
||||
GInputStream *input = g_memory_input_stream_new_from_bytes (bytes);
|
||||
gssize spliced;
|
||||
|
||||
spliced = g_output_stream_splice (gdk_content_serializer_get_output_stream (serializer),
|
||||
input,
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
&error);
|
||||
g_object_unref (input);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
result = spliced != -1;
|
||||
}
|
||||
else
|
||||
g_set_error_literal (&error,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Saving png failed");
|
||||
|
||||
if (result)
|
||||
g_task_return_boolean (task, result);
|
||||
else
|
||||
g_task_return_error (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
task = g_task_new (serializer,
|
||||
gdk_content_serializer_get_cancellable (serializer),
|
||||
texture_serializer_finish,
|
||||
NULL);
|
||||
g_task_run_in_thread (task, serialize_texture_in_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
string_serializer_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@@ -877,51 +957,66 @@ init (void)
|
||||
|
||||
initialized = TRUE;
|
||||
|
||||
gdk_content_register_serializer (GDK_TYPE_TEXTURE,
|
||||
"image/png",
|
||||
texture_serializer,
|
||||
NULL, NULL);
|
||||
|
||||
gdk_content_register_serializer (GDK_TYPE_TEXTURE,
|
||||
"image/tiff",
|
||||
texture_serializer,
|
||||
NULL, NULL);
|
||||
|
||||
formats = gdk_pixbuf_get_formats ();
|
||||
|
||||
/* Make sure png comes first */
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char *name;
|
||||
|
||||
char *name;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
if (g_str_equal (name, "png"))
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
{
|
||||
formats = g_slist_delete_link (formats, f);
|
||||
formats = g_slist_prepend (formats, fmt);
|
||||
|
||||
g_free (name);
|
||||
|
||||
break;
|
||||
}
|
||||
g_free (name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
}
|
||||
|
||||
for (f = formats; f; f = f->next)
|
||||
{
|
||||
GdkPixbufFormat *fmt = f->data;
|
||||
char **mimes, **m;
|
||||
char *name;
|
||||
|
||||
if (!gdk_pixbuf_format_is_writable (fmt))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
name = gdk_pixbuf_format_get_name (fmt);
|
||||
mimes = gdk_pixbuf_format_get_mime_types (fmt);
|
||||
for (m = mimes; *m; m++)
|
||||
{
|
||||
gdk_content_register_serializer (GDK_TYPE_TEXTURE,
|
||||
*m,
|
||||
pixbuf_serializer,
|
||||
gdk_pixbuf_format_get_name (fmt),
|
||||
g_free);
|
||||
{
|
||||
/* Turning textures into pngs or tiffs is handled above */
|
||||
if (!g_str_equal (name, "png") &&
|
||||
!g_str_equal (name, "tiff"))
|
||||
gdk_content_register_serializer (GDK_TYPE_TEXTURE,
|
||||
*m,
|
||||
pixbuf_serializer,
|
||||
gdk_pixbuf_format_get_name (fmt),
|
||||
g_free);
|
||||
gdk_content_register_serializer (GDK_TYPE_PIXBUF,
|
||||
*m,
|
||||
pixbuf_serializer,
|
||||
gdk_pixbuf_format_get_name (fmt),
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
g_strfreev (mimes);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
+6
-4
@@ -41,10 +41,12 @@ typedef enum {
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 15,
|
||||
GDK_DEBUG_GL_GLES = 1 << 16,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 17,
|
||||
GDK_DEBUG_GL_GLX = 1 << 18,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 19,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 20,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 21
|
||||
GDK_DEBUG_GL_EGL = 1 << 18,
|
||||
GDK_DEBUG_GL_GLX = 1 << 19,
|
||||
GDK_DEBUG_GL_WGL = 1 << 20,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 21,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 22,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 23,
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
|
||||
+183
-33
@@ -77,6 +77,23 @@ enum {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
typedef struct _GdkDisplayPrivate GdkDisplayPrivate;
|
||||
|
||||
struct _GdkDisplayPrivate {
|
||||
/* The base context that all other contexts inherit from.
|
||||
* This context is never exposed to public API and is
|
||||
* allowed to have a %NULL surface.
|
||||
*/
|
||||
GdkGLContext *gl_context;
|
||||
GError *gl_error;
|
||||
|
||||
guint rgba : 1;
|
||||
guint composited : 1;
|
||||
guint input_shapes : 1;
|
||||
|
||||
GdkDebugFlags debug_flags;
|
||||
};
|
||||
|
||||
static void gdk_display_dispose (GObject *object);
|
||||
static void gdk_display_finalize (GObject *object);
|
||||
|
||||
@@ -85,7 +102,7 @@ static GdkAppLaunchContext *gdk_display_real_get_app_launch_context (GdkDisplay
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_display_get_property (GObject *object,
|
||||
@@ -119,10 +136,14 @@ gdk_display_real_make_default (GdkDisplay *display)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_real_opened (GdkDisplay *display)
|
||||
static GdkGLContext *
|
||||
gdk_display_default_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
_gdk_display_manager_add_display (gdk_display_manager_get (), display);
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("The current backend does not support OpenGL"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkSeat *
|
||||
@@ -134,6 +155,12 @@ gdk_display_real_get_default_seat (GdkDisplay *display)
|
||||
return display->seats->data;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_real_opened (GdkDisplay *display)
|
||||
{
|
||||
_gdk_display_manager_add_display (gdk_display_manager_get (), display);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_class_init (GdkDisplayClass *class)
|
||||
{
|
||||
@@ -143,10 +170,11 @@ gdk_display_class_init (GdkDisplayClass *class)
|
||||
object_class->dispose = gdk_display_dispose;
|
||||
object_class->get_property = gdk_display_get_property;
|
||||
|
||||
class->get_app_launch_context = gdk_display_real_get_app_launch_context;
|
||||
class->opened = gdk_display_real_opened;
|
||||
class->make_default = gdk_display_real_make_default;
|
||||
class->get_app_launch_context = gdk_display_real_get_app_launch_context;
|
||||
class->init_gl = gdk_display_default_init_gl;
|
||||
class->get_default_seat = gdk_display_real_get_default_seat;
|
||||
class->opened = gdk_display_real_opened;
|
||||
|
||||
/**
|
||||
* GdkDisplay:composited: (attributes org.gtk.Property.get=gdk_display_is_composited)
|
||||
@@ -294,6 +322,8 @@ free_device_grabs_foreach (gpointer key,
|
||||
static void
|
||||
gdk_display_init (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
display->double_click_time = 250;
|
||||
display->double_click_distance = 5;
|
||||
|
||||
@@ -304,22 +334,26 @@ gdk_display_init (GdkDisplay *display)
|
||||
|
||||
g_queue_init (&display->queued_events);
|
||||
|
||||
display->debug_flags = _gdk_debug_flags;
|
||||
priv->debug_flags = _gdk_debug_flags;
|
||||
|
||||
display->composited = TRUE;
|
||||
display->rgba = TRUE;
|
||||
display->input_shapes = TRUE;
|
||||
priv->composited = TRUE;
|
||||
priv->rgba = TRUE;
|
||||
priv->input_shapes = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_dispose (GObject *object)
|
||||
{
|
||||
GdkDisplay *display = GDK_DISPLAY (object);
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
_gdk_display_manager_remove_display (gdk_display_manager_get (), display);
|
||||
|
||||
g_queue_clear (&display->queued_events);
|
||||
|
||||
g_clear_object (&priv->gl_context);
|
||||
g_clear_error (&priv->gl_error);
|
||||
|
||||
G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -998,21 +1032,25 @@ gdk_display_get_primary_clipboard (GdkDisplay *display)
|
||||
gboolean
|
||||
gdk_display_supports_input_shapes (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
return display->input_shapes;
|
||||
return priv->input_shapes;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_input_shapes (GdkDisplay *display,
|
||||
gboolean input_shapes)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (display->input_shapes == input_shapes)
|
||||
if (priv->input_shapes == input_shapes)
|
||||
return;
|
||||
|
||||
display->input_shapes = input_shapes;
|
||||
priv->input_shapes = input_shapes;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_INPUT_SHAPES]);
|
||||
}
|
||||
@@ -1157,32 +1195,136 @@ gdk_display_get_keymap (GdkDisplay *display)
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_display_make_gl_context_current:
|
||||
* @display: a `GdkDisplay`
|
||||
* @context: (optional): a `GdkGLContext`
|
||||
*
|
||||
* Makes the given @context the current GL context, or unsets
|
||||
* the current GL context if @context is %NULL.
|
||||
*/
|
||||
gboolean
|
||||
gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
static void
|
||||
gdk_display_init_gl (GdkDisplay *self)
|
||||
{
|
||||
return GDK_DISPLAY_GET_CLASS (display)->make_gl_context_current (display, context);
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
GdkGLContext *context;
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
gint64 before2 G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (self, GL_DISABLE))
|
||||
{
|
||||
g_set_error_literal (&priv->gl_error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("GL support disabled via GDK_DEBUG"));
|
||||
return;
|
||||
}
|
||||
|
||||
context = GDK_DISPLAY_GET_CLASS (self)->init_gl (self, &priv->gl_error);
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
before2 = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (!gdk_gl_context_realize (context, &priv->gl_error))
|
||||
{
|
||||
g_object_unref (context);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_profiler_end_mark (before2, "realize OpenGL context", NULL);
|
||||
|
||||
/* Only assign after realize, so GdkGLContext::realize() can use
|
||||
* gdk_display_get_gl_context() == NULL to differentiate between
|
||||
* the display's context and any other context.
|
||||
*/
|
||||
priv->gl_context = context;
|
||||
|
||||
gdk_profiler_end_mark (before, "initialize OpenGL", NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_prepare_gl:
|
||||
* @self: a `GdkDisplay`
|
||||
* @error: return location for a `GError`
|
||||
*
|
||||
* Checks that OpenGL is available for @self and ensures that it is
|
||||
* properly initialized.
|
||||
* When this fails, an @error will be set describing the error and this
|
||||
* function returns %FALSE.
|
||||
*
|
||||
* Note that even if this function succeeds, creating a `GdkGLContext`
|
||||
* may still fail.
|
||||
*
|
||||
* This function is idempotent. Calling it multiple times will just
|
||||
* return the same value or error.
|
||||
*
|
||||
* You never need to call this function, GDK will call it automatically
|
||||
* as needed. But you can use it as a check when setting up code that
|
||||
* might make use of OpenGL.
|
||||
*
|
||||
* Returns: %TRUE if the display supports OpenGL
|
||||
*
|
||||
* Since: 4.4
|
||||
**/
|
||||
gboolean
|
||||
gdk_display_prepare_gl (GdkDisplay *self,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (priv->gl_context)
|
||||
return TRUE;
|
||||
|
||||
if (priv->gl_error != NULL)
|
||||
{
|
||||
if (error)
|
||||
*error = g_error_copy (priv->gl_error);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_display_init_gl (self);
|
||||
|
||||
/* try again */
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_display_get_gl_context:
|
||||
* @self: the `GdkDisplay`
|
||||
*
|
||||
* Gets the GL context returned from [vfunc@Gdk.Display.init_gl]
|
||||
* previously.
|
||||
*
|
||||
* If that function has not been called yet or did fail, %NULL is
|
||||
* returned.
|
||||
* Call [method@Gdk.Display.prepare_gl] to avoid this.
|
||||
*
|
||||
* Returns: The `GdkGLContext`
|
||||
*/
|
||||
GdkGLContext *
|
||||
gdk_display_get_gl_context (GdkDisplay *self)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
return priv->gl_context;
|
||||
}
|
||||
|
||||
GdkDebugFlags
|
||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||
{
|
||||
return display ? display->debug_flags : _gdk_debug_flags;
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
return display ? priv->debug_flags : _gdk_debug_flags;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
GdkDebugFlags flags)
|
||||
{
|
||||
display->debug_flags = flags;
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
priv->debug_flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1207,21 +1349,25 @@ gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
gboolean
|
||||
gdk_display_is_composited (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
return display->composited;
|
||||
return priv->composited;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_composited (GdkDisplay *display,
|
||||
gboolean composited)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (display->composited == composited)
|
||||
if (priv->composited == composited)
|
||||
return;
|
||||
|
||||
display->composited = composited;
|
||||
priv->composited = composited;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_COMPOSITED]);
|
||||
}
|
||||
@@ -1248,21 +1394,25 @@ gdk_display_set_composited (GdkDisplay *display,
|
||||
gboolean
|
||||
gdk_display_is_rgba (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
return display->rgba;
|
||||
return priv->rgba;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_rgba (GdkDisplay *display,
|
||||
gboolean rgba)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (display->rgba == rgba)
|
||||
if (priv->rgba == rgba)
|
||||
return;
|
||||
|
||||
display->rgba = rgba;
|
||||
priv->rgba = rgba;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_RGBA]);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,10 @@ gboolean gdk_display_is_rgba (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
gboolean gdk_display_prepare_gl (GdkDisplay *self,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay *gdk_display_get_default (void);
|
||||
|
||||
|
||||
@@ -102,11 +102,6 @@ struct _GdkDisplay
|
||||
|
||||
guint vulkan_refcount;
|
||||
#endif /* GDK_RENDERING_VULKAN */
|
||||
guint rgba : 1;
|
||||
guint composited : 1;
|
||||
guint input_shapes : 1;
|
||||
|
||||
GdkDebugFlags debug_flags;
|
||||
|
||||
GList *seats;
|
||||
};
|
||||
@@ -145,8 +140,8 @@ struct _GdkDisplayClass
|
||||
|
||||
GdkKeymap * (*get_keymap) (GdkDisplay *display);
|
||||
|
||||
gboolean (*make_gl_context_current) (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
GdkGLContext * (*init_gl) (GdkDisplay *display,
|
||||
GError **error);
|
||||
|
||||
GdkSeat * (*get_default_seat) (GdkDisplay *display);
|
||||
|
||||
@@ -211,8 +206,7 @@ GdkSurface * gdk_display_create_surface (GdkDisplay *display
|
||||
int width,
|
||||
int height);
|
||||
|
||||
gboolean gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
|
||||
|
||||
void gdk_display_set_rgba (GdkDisplay *display,
|
||||
gboolean rgba);
|
||||
|
||||
+28
-4
@@ -43,6 +43,7 @@
|
||||
typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate;
|
||||
|
||||
struct _GdkDrawContextPrivate {
|
||||
GdkDisplay *display;
|
||||
GdkSurface *surface;
|
||||
|
||||
cairo_region_t *frame_region;
|
||||
@@ -77,6 +78,7 @@ gdk_draw_context_dispose (GObject *gobject)
|
||||
priv->surface->draw_contexts = g_slist_remove (priv->surface->draw_contexts, context);
|
||||
g_clear_object (&priv->surface);
|
||||
}
|
||||
g_clear_object (&priv->display);
|
||||
|
||||
G_OBJECT_CLASS (gdk_draw_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
@@ -92,10 +94,31 @@ gdk_draw_context_set_property (GObject *gobject,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
if (priv->display != NULL)
|
||||
{
|
||||
g_assert (g_value_get_object (value) == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->display = g_value_dup_object (value);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SURFACE:
|
||||
priv->surface = g_value_dup_object (value);
|
||||
g_assert (priv->surface != NULL);
|
||||
priv->surface->draw_contexts = g_slist_prepend (priv->surface->draw_contexts, context);
|
||||
if (priv->surface)
|
||||
{
|
||||
priv->surface->draw_contexts = g_slist_prepend (priv->surface->draw_contexts, context);
|
||||
if (priv->display)
|
||||
{
|
||||
g_assert (priv->display == gdk_surface_get_display (priv->surface));
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->display = g_object_ref (gdk_surface_get_display (priv->surface));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -148,7 +171,8 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
||||
P_("Display"),
|
||||
P_("The GDK display used to create the context"),
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
@@ -228,7 +252,7 @@ gdk_draw_context_get_display (GdkDrawContext *context)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (context), NULL);
|
||||
|
||||
return priv->surface ? gdk_surface_get_display (priv->surface) : NULL;
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkframeclockprivate.h"
|
||||
#include "gdk.h"
|
||||
#include "gdk-private.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
@@ -307,12 +308,15 @@ maybe_start_idle (GdkFrameClockIdle *clock_idle,
|
||||
|
||||
if (priv->flush_idle_id == 0 && RUN_FLUSH_IDLE (priv))
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
priv->flush_idle_id = g_timeout_add_full (GDK_PRIORITY_EVENTS + 1,
|
||||
min_interval,
|
||||
gdk_frame_clock_flush_idle,
|
||||
g_object_ref (clock_idle),
|
||||
(GDestroyNotify) g_object_unref);
|
||||
g_source_set_name_by_id (priv->flush_idle_id, "[gtk] gdk_frame_clock_flush_idle");
|
||||
source = g_main_context_find_source_by_id (NULL, priv->flush_idle_id);
|
||||
g_source_set_static_name (source, "[gtk] gdk_frame_clock_flush_idle");
|
||||
}
|
||||
|
||||
if (!priv->in_paint_idle &&
|
||||
@@ -324,7 +328,7 @@ maybe_start_idle (GdkFrameClockIdle *clock_idle,
|
||||
gdk_frame_clock_paint_idle,
|
||||
g_object_ref (clock_idle),
|
||||
(GDestroyNotify) g_object_unref);
|
||||
g_source_set_name_by_id (priv->paint_idle_id, "[gtk] gdk_frame_clock_paint_idle");
|
||||
gdk_source_set_static_name_by_id (priv->paint_idle_id, "[gtk] gdk_frame_clock_paint_idle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -301,7 +301,7 @@ gdk_gl_texture_quads (GdkGLContext *paint_context,
|
||||
* @width: The width of the region to draw
|
||||
* @height: The height of the region to draw
|
||||
*
|
||||
* The main way to draw GL content in GTK.
|
||||
* The main way to not draw GL content in GTK.
|
||||
*
|
||||
* It takes a render buffer ID (@source_type == GL_RENDERBUFFER) or a texture
|
||||
* id (@source_type == GL_TEXTURE) and draws it onto @cr with an OVER operation,
|
||||
@@ -319,6 +319,12 @@ gdk_gl_texture_quads (GdkGLContext *paint_context,
|
||||
* with alpha components, so make sure you use GL_TEXTURE if using alpha.
|
||||
*
|
||||
* Calling this may change the current GL context.
|
||||
*
|
||||
* Deprecated: 4.6: The function is overly complex and produces broken output
|
||||
* in various combinations of arguments. If you want to draw with GL textures
|
||||
* in GTK, use [ctor@Gdk.GLTexture.new]; if you want to use that texture in
|
||||
* Cairo, use [method@Gdk.Texture.download] to download the data into a Cairo
|
||||
* image surface.
|
||||
*/
|
||||
void
|
||||
gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
|
||||
+202
-106
@@ -89,8 +89,6 @@
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
typedef struct {
|
||||
GdkGLContext *shared_context;
|
||||
|
||||
int major;
|
||||
int minor;
|
||||
int gl_version;
|
||||
@@ -127,7 +125,28 @@ G_DEFINE_QUARK (gdk-gl-error-quark, gdk_gl_error)
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, GDK_TYPE_DRAW_CONTEXT)
|
||||
|
||||
static GPrivate thread_current_context = G_PRIVATE_INIT (g_object_unref);
|
||||
typedef struct _MaskedContext MaskedContext;
|
||||
|
||||
static inline MaskedContext *
|
||||
mask_context (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
return (MaskedContext *) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (context) | (surfaceless ? 1 : 0));
|
||||
}
|
||||
|
||||
static inline GdkGLContext *
|
||||
unmask_context (MaskedContext *mask)
|
||||
{
|
||||
return GDK_GL_CONTEXT (GSIZE_TO_POINTER (GPOINTER_TO_SIZE (mask) & ~(gsize) 1));
|
||||
}
|
||||
|
||||
static void
|
||||
unref_unmasked (gpointer data)
|
||||
{
|
||||
g_object_unref (unmask_context (data));
|
||||
}
|
||||
|
||||
static GPrivate thread_current_context = G_PRIVATE_INIT (unref_unmasked);
|
||||
|
||||
static void
|
||||
gdk_gl_context_clear_old_updated_area (GdkGLContext *context)
|
||||
@@ -144,17 +163,14 @@ static void
|
||||
gdk_gl_context_dispose (GObject *gobject)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current;
|
||||
|
||||
gdk_gl_context_clear_old_updated_area (context);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current == context)
|
||||
if (unmask_context (current) == context)
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
|
||||
g_clear_object (&priv->shared_context);
|
||||
|
||||
G_OBJECT_CLASS (gdk_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
@@ -174,17 +190,10 @@ gdk_gl_context_set_property (GObject *gobject,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SHARED_CONTEXT:
|
||||
{
|
||||
GdkGLContext *context = g_value_get_object (value);
|
||||
|
||||
if (context != NULL)
|
||||
priv->shared_context = g_object_ref (context);
|
||||
}
|
||||
g_assert (g_value_get_object (value) == NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -198,12 +207,10 @@ gdk_gl_context_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private ((GdkGLContext *) gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SHARED_CONTEXT:
|
||||
g_value_set_object (value, priv->shared_context);
|
||||
g_value_set_object (value, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -222,64 +229,83 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
guchar *copy = NULL;
|
||||
guint gl_format;
|
||||
guint gl_type;
|
||||
guint bpp;
|
||||
GLint gl_internalformat;
|
||||
GLint gl_format;
|
||||
GLint gl_type;
|
||||
gsize bpp;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
if (priv->use_es)
|
||||
if (!priv->use_es && data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
|
||||
{
|
||||
/* GLES only supports rgba, so convert if necessary */
|
||||
if (data_format != GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
{
|
||||
copy = g_malloc (width * height * 4);
|
||||
gdk_memory_convert (copy, width * 4,
|
||||
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||
data, stride, data_format,
|
||||
width, height);
|
||||
stride = width * 4;
|
||||
data = copy;
|
||||
}
|
||||
|
||||
bpp = 4;
|
||||
gl_internalformat = GL_RGBA8;
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */
|
||||
{
|
||||
gl_internalformat = GL_RGBA8;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else if (priv->use_es && data_format == GDK_MEMORY_B8G8R8)
|
||||
{
|
||||
gl_internalformat = GL_RGBA8;
|
||||
gl_format = GL_BGR;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R16G16B16)
|
||||
{
|
||||
gl_internalformat = GL_RGBA16;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_UNSIGNED_SHORT;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R16G16B16A16_PREMULTIPLIED)
|
||||
{
|
||||
gl_internalformat = GL_RGBA16;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_SHORT;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R16G16B16_FLOAT)
|
||||
{
|
||||
gl_internalformat = GL_RGB16F;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_HALF_FLOAT;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED)
|
||||
{
|
||||
gl_internalformat = GL_RGBA16F;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_HALF_FLOAT;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R32G32B32_FLOAT)
|
||||
{
|
||||
gl_internalformat = GL_RGB32F;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_FLOAT;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED)
|
||||
{
|
||||
gl_internalformat = GL_RGBA32F;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_FLOAT;
|
||||
}
|
||||
else /* Fall-back, convert to GLES format */
|
||||
{
|
||||
copy = g_malloc (width * height * 4);
|
||||
gdk_memory_convert (copy, width * 4,
|
||||
GDK_MEMORY_CONVERT_GLES_RGBA,
|
||||
data, stride, data_format,
|
||||
width, height);
|
||||
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
stride = width * 4;
|
||||
data = copy;
|
||||
gl_internalformat = GL_RGBA8;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
|
||||
{
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
bpp = 4;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */
|
||||
{
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
bpp = 3;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_B8G8R8)
|
||||
{
|
||||
gl_format = GL_BGR;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
bpp = 3;
|
||||
}
|
||||
else /* Fall-back, convert to cairo-surface-format */
|
||||
{
|
||||
copy = g_malloc (width * height * 4);
|
||||
gdk_memory_convert (copy, width * 4,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
data, stride, data_format,
|
||||
width, height);
|
||||
stride = width * 4;
|
||||
bpp = 4;
|
||||
data = copy;
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
}
|
||||
|
||||
bpp = gdk_memory_format_bytes_per_pixel (data_format);
|
||||
|
||||
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
|
||||
* the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
|
||||
@@ -288,7 +314,7 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
|
||||
glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
|
||||
}
|
||||
else if ((!priv->use_es ||
|
||||
@@ -296,14 +322,14 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
|
||||
|
||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
|
||||
glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
|
||||
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, NULL);
|
||||
glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL);
|
||||
for (i = 0; i < height; i++)
|
||||
glTexSubImage2D (texture_target, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
|
||||
}
|
||||
@@ -333,23 +359,27 @@ gdk_gl_context_real_get_damage (GdkGLContext *context)
|
||||
});
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_is_shared (GdkGLContext *self,
|
||||
GdkGLContext *other)
|
||||
{
|
||||
if (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self)) != gdk_draw_context_get_display (GDK_DRAW_CONTEXT (other)))
|
||||
return FALSE;
|
||||
|
||||
/* XXX: Should we check es or legacy here? */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface;
|
||||
GdkGLContext *shared;
|
||||
cairo_region_t *damage;
|
||||
int ww, wh;
|
||||
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
if (shared)
|
||||
{
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (GDK_DRAW_CONTEXT (shared))->begin_frame (GDK_DRAW_CONTEXT (shared), region);
|
||||
return;
|
||||
}
|
||||
|
||||
damage = GDK_GL_CONTEXT_GET_CLASS (context)->get_damage (context);
|
||||
|
||||
if (context->old_updated_area[1])
|
||||
@@ -379,15 +409,6 @@ static void
|
||||
gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkGLContext *shared;
|
||||
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
if (shared)
|
||||
{
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (GDK_DRAW_CONTEXT (shared))->end_frame (GDK_DRAW_CONTEXT (shared), painted);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -406,6 +427,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
|
||||
klass->realize = gdk_gl_context_real_realize;
|
||||
klass->get_damage = gdk_gl_context_real_get_damage;
|
||||
klass->is_shared = gdk_gl_context_real_is_shared;
|
||||
|
||||
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
|
||||
draw_context_class->end_frame = gdk_gl_context_real_end_frame;
|
||||
@@ -414,7 +436,13 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
/**
|
||||
* GdkGLContext:shared-context: (attributes org.gtk.Property.get=gdk_gl_context_get_shared_context)
|
||||
*
|
||||
* The `GdkGLContext` that this context is sharing data with, or %NULL
|
||||
* Always %NULL
|
||||
*
|
||||
* As many contexts can share data now and no single shared context exists
|
||||
* anymore, this function has been deprecated and now always returns %NULL.
|
||||
*
|
||||
* Deprecated: 4.4: Use [method@Gdk.GLContext.is_shared] to check if contexts
|
||||
* can be shared.
|
||||
*/
|
||||
obj_pspecs[PROP_SHARED_CONTEXT] =
|
||||
g_param_spec_object ("shared-context",
|
||||
@@ -423,7 +451,8 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
GDK_TYPE_GL_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_DEPRECATED);
|
||||
|
||||
gobject_class->set_property = gdk_gl_context_set_property;
|
||||
gobject_class->get_property = gdk_gl_context_get_property;
|
||||
@@ -441,6 +470,21 @@ gdk_gl_context_init (GdkGLContext *self)
|
||||
priv->use_es = -1;
|
||||
}
|
||||
|
||||
/* Must have called gdk_display_prepare_gl() before */
|
||||
GdkGLContext *
|
||||
gdk_gl_context_new_for_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkGLContext *shared = gdk_display_get_gl_context (display);
|
||||
|
||||
/* assert gdk_display_prepare_gl() had been called */
|
||||
g_assert (shared);
|
||||
|
||||
return g_object_new (G_OBJECT_TYPE (shared),
|
||||
"surface", surface,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GdkGLContextPaintData *
|
||||
gdk_gl_context_get_paint_data (GdkGLContext *context)
|
||||
{
|
||||
@@ -812,6 +856,44 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
priv->is_legacy = !!is_legacy;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_is_shared:
|
||||
* @self: a `GdkGLContext`
|
||||
* @other: the `GdkGLContext` that should be compatible with @self
|
||||
*
|
||||
* Checks if the two GL contexts can share resources.
|
||||
*
|
||||
* When they can, the texture IDs from @other can be used in @self. This
|
||||
* is particularly useful when passing `GdkGLTexture` objects between
|
||||
* different contexts.
|
||||
*
|
||||
* Contexts created for the same display with the same properties will
|
||||
* always be compatible, even if they are created for different surfaces.
|
||||
* For other contexts it depends on the GL backend.
|
||||
*
|
||||
* Both contexts must be realized for this check to succeed. If either one
|
||||
* is not, this function will return %FALSE.
|
||||
*
|
||||
* Returns: %TRUE if the two GL contexts are compatible.
|
||||
*
|
||||
* Since: 4.4
|
||||
*/
|
||||
gboolean
|
||||
gdk_gl_context_is_shared (GdkGLContext *self,
|
||||
GdkGLContext *other)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
GdkGLContextPrivate *priv_other = gdk_gl_context_get_instance_private (other);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (other), FALSE);
|
||||
|
||||
if (!priv->realized || !priv_other->realized)
|
||||
return FALSE;
|
||||
|
||||
return GDK_GL_CONTEXT_GET_CLASS (self)->is_shared (self, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_set_use_es:
|
||||
* @context: a `GdkGLContext`
|
||||
@@ -1092,12 +1174,16 @@ void
|
||||
gdk_gl_context_make_current (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current, *masked_context;
|
||||
gboolean surfaceless;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
|
||||
masked_context = mask_context (context, surfaceless);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current == context)
|
||||
if (current == masked_context)
|
||||
return;
|
||||
|
||||
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
||||
@@ -1114,11 +1200,15 @@ gdk_gl_context_make_current (GdkGLContext *context)
|
||||
}
|
||||
}
|
||||
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), context))
|
||||
if (!GDK_GL_CONTEXT_GET_CLASS (context)->make_current (context, surfaceless))
|
||||
{
|
||||
g_private_replace (&thread_current_context, g_object_ref (context));
|
||||
gdk_gl_context_check_extensions (context);
|
||||
g_warning ("gdk_gl_context_make_current() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_ref (context);
|
||||
g_private_replace (&thread_current_context, masked_context);
|
||||
gdk_gl_context_check_extensions (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1157,18 +1247,22 @@ gdk_gl_context_get_surface (GdkGLContext *context)
|
||||
* gdk_gl_context_get_shared_context: (attributes org.gtk.Method.get_property=shared-context)
|
||||
* @context: a `GdkGLContext`
|
||||
*
|
||||
* Retrieves the `GdkGLContext` that this @context share data with.
|
||||
* Used to retrieves the `GdkGLContext` that this @context share data with.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a `GdkGLContext`
|
||||
* As many contexts can share data now and no single shared context exists
|
||||
* anymore, this function has been deprecated and now always returns %NULL.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): %NULL
|
||||
*
|
||||
* Deprecated: 4.4: Use [method@Gdk.GLContext.is_shared] to check if contexts
|
||||
* can be shared.
|
||||
*/
|
||||
GdkGLContext *
|
||||
gdk_gl_context_get_shared_context (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
|
||||
|
||||
return priv->shared_context;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1208,12 +1302,14 @@ gdk_gl_context_get_version (GdkGLContext *context,
|
||||
void
|
||||
gdk_gl_context_clear_current (void)
|
||||
{
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current != NULL)
|
||||
{
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (current)), NULL))
|
||||
GdkGLContext *context = unmask_context (current);
|
||||
|
||||
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
}
|
||||
}
|
||||
@@ -1228,11 +1324,11 @@ gdk_gl_context_clear_current (void)
|
||||
GdkGLContext *
|
||||
gdk_gl_context_get_current (void)
|
||||
{
|
||||
GdkGLContext *current;
|
||||
MaskedContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
|
||||
return current;
|
||||
return unmask_context (current);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
+5
-2
@@ -45,8 +45,8 @@ GType gdk_gl_context_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gdk_gl_context_get_display (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_gl_context_get_surface (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_gl_context_get_surface (GdkGLContext *context);
|
||||
GDK_DEPRECATED_IN_4_4_FOR(gdk_gl_context_is_shared)
|
||||
GdkGLContext * gdk_gl_context_get_shared_context (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_gl_context_get_version (GdkGLContext *context,
|
||||
@@ -54,6 +54,9 @@ void gdk_gl_context_get_version (GdkGLContext *
|
||||
int *minor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_gl_context_is_legacy (GdkGLContext *context);
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
gboolean gdk_gl_context_is_shared (GdkGLContext *self,
|
||||
GdkGLContext *other);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_gl_context_set_required_version (GdkGLContext *context,
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Version requirements for EGL contexts.
|
||||
*
|
||||
* If you add support for EGL to your backend, please require this.
|
||||
*/
|
||||
#define GDK_EGL_MIN_VERSION_MAJOR (1)
|
||||
#define GDK_EGL_MIN_VERSION_MINOR (4)
|
||||
|
||||
#define GDK_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
||||
#define GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT))
|
||||
#define GDK_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
||||
@@ -45,10 +52,16 @@ struct _GdkGLContextClass
|
||||
{
|
||||
GdkDrawContextClass parent_class;
|
||||
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
gboolean (* make_current) (GdkGLContext *context,
|
||||
gboolean surfaceless);
|
||||
gboolean (* clear_current) (GdkGLContext *context);
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
|
||||
gboolean (* is_shared) (GdkGLContext *self,
|
||||
GdkGLContext *other);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -73,6 +86,8 @@ typedef struct {
|
||||
guint use_es : 1;
|
||||
} GdkGLContextPaintData;
|
||||
|
||||
GdkGLContext * gdk_gl_context_new_for_surface (GdkSurface *surface);
|
||||
|
||||
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
gboolean is_legacy);
|
||||
|
||||
|
||||
+223
-45
@@ -20,7 +20,8 @@
|
||||
|
||||
#include "gdkgltextureprivate.h"
|
||||
|
||||
#include "gdkcairo.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
@@ -37,7 +38,7 @@ struct _GdkGLTexture {
|
||||
GdkGLContext *context;
|
||||
guint id;
|
||||
|
||||
cairo_surface_t *saved;
|
||||
GdkTexture *saved;
|
||||
|
||||
GDestroyNotify destroy;
|
||||
gpointer data;
|
||||
@@ -64,50 +65,239 @@ gdk_gl_texture_dispose (GObject *object)
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
|
||||
if (self->saved)
|
||||
{
|
||||
cairo_surface_destroy (self->saved);
|
||||
self->saved = NULL;
|
||||
}
|
||||
g_clear_object (&self->saved);
|
||||
|
||||
G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
typedef struct _InvokeData
|
||||
{
|
||||
GdkGLTexture *self;
|
||||
volatile int spinlock;
|
||||
GFunc func;
|
||||
gpointer data;
|
||||
} InvokeData;
|
||||
|
||||
static gboolean
|
||||
gdk_gl_texture_invoke_callback (gpointer data)
|
||||
{
|
||||
InvokeData *invoke = data;
|
||||
GdkGLContext *context;
|
||||
|
||||
context = gdk_display_get_gl_context (gdk_gl_context_get_display (invoke->self->context));
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
glBindTexture (GL_TEXTURE_2D, invoke->self->id);
|
||||
|
||||
invoke->func (invoke->self, invoke->data);
|
||||
|
||||
g_atomic_int_set (&invoke->spinlock, 1);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_download (GdkTexture *texture,
|
||||
const GdkRectangle *area,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
gdk_gl_texture_run (GdkGLTexture *self,
|
||||
GFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
InvokeData invoke = { self, 0, func, data };
|
||||
|
||||
g_main_context_invoke (NULL, gdk_gl_texture_invoke_callback, &invoke);
|
||||
|
||||
while (g_atomic_int_get (&invoke.spinlock) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_do_download_texture (gpointer texture_,
|
||||
gpointer result_)
|
||||
{
|
||||
GdkTexture *texture = texture_;
|
||||
GdkTexture **result = result_;
|
||||
GdkMemoryFormat format;
|
||||
GLint internal_format, gl_format, gl_type;
|
||||
guchar *data;
|
||||
gsize stride;
|
||||
GBytes *bytes;
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
|
||||
|
||||
switch (internal_format)
|
||||
{
|
||||
case GL_RGB8:
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
case GL_RGBA8:
|
||||
format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
case GL_RGB16:
|
||||
format = GDK_MEMORY_R16G16B16;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
|
||||
case GL_RGBA16:
|
||||
format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
|
||||
case GL_RGB16F:
|
||||
format = GDK_MEMORY_R16G16B16_FLOAT;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_HALF_FLOAT;
|
||||
break;
|
||||
|
||||
case GL_RGBA16F:
|
||||
format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_HALF_FLOAT;
|
||||
break;
|
||||
|
||||
case GL_RGB32F:
|
||||
format = GDK_MEMORY_R32G32B32_FLOAT;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_FLOAT;
|
||||
break;
|
||||
|
||||
case GL_RGBA32F:
|
||||
format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_FLOAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Texture in unexpected format 0x%X (%d). File a bug about adding it to GTK", internal_format, internal_format);
|
||||
/* fallback to the dumbest possible format
|
||||
* so that even age old GLES can do it */
|
||||
format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
}
|
||||
|
||||
stride = gdk_memory_format_bytes_per_pixel (format) * texture->width;
|
||||
data = g_malloc (stride * texture->height);
|
||||
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_format,
|
||||
gl_type,
|
||||
data);
|
||||
|
||||
bytes = g_bytes_new_take (data, stride * texture->height);
|
||||
*result = gdk_memory_texture_new (texture->width,
|
||||
texture->height,
|
||||
format,
|
||||
bytes,
|
||||
stride);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
gdk_gl_texture_download_texture (GdkTexture *texture)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (texture);
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkTexture *result;
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
area->width, area->height,
|
||||
stride);
|
||||
if (self->saved)
|
||||
return g_object_ref (self->saved);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
gdk_gl_texture_run (self, gdk_gl_texture_do_download_texture, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_do_download (gpointer texture,
|
||||
gpointer data)
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_BGRA,
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
GL_UNSIGNED_BYTE,
|
||||
#else
|
||||
#error "Unknown byte order for gdk_gl_texture_download()"
|
||||
#endif
|
||||
data);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_download (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (texture);
|
||||
|
||||
if (self->saved)
|
||||
{
|
||||
cairo_set_source_surface (cr, self->saved, 0, 0);
|
||||
cairo_paint (cr);
|
||||
gdk_texture_download (self->saved, data, stride);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (gdk_gl_context_get_use_es (self->context) ||
|
||||
stride != texture->width * 4)
|
||||
{
|
||||
GdkSurface *gl_surface;
|
||||
|
||||
gl_surface = gdk_gl_context_get_surface (self->context);
|
||||
gdk_cairo_draw_from_gl (cr, gl_surface, self->id, GL_TEXTURE, 1,
|
||||
area->x, area->y,
|
||||
area->width, area->height);
|
||||
GDK_TEXTURE_CLASS (gdk_gl_texture_parent_class)->download (texture, data, stride);
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_finish (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
gdk_gl_texture_run (self, gdk_gl_texture_do_download, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_do_download_float (gpointer texture,
|
||||
gpointer data)
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
data);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_download_float (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (texture);
|
||||
int width, height, y;
|
||||
float *copy;
|
||||
|
||||
if (self->saved)
|
||||
{
|
||||
gdk_texture_download_float (self->saved, data, stride);
|
||||
return;
|
||||
}
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
|
||||
if (stride == width * 4)
|
||||
{
|
||||
gdk_gl_texture_run (self, gdk_gl_texture_do_download_float, data);
|
||||
return;
|
||||
}
|
||||
|
||||
copy = g_new (float, width * height * 4);
|
||||
|
||||
gdk_gl_texture_run (self, gdk_gl_texture_do_download_float, copy);
|
||||
for (y = 0; y < height; y++)
|
||||
memcpy (data + y * stride, copy + y * 4 * width, 4 * width);
|
||||
|
||||
g_free (copy);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -116,7 +306,9 @@ gdk_gl_texture_class_init (GdkGLTextureClass *klass)
|
||||
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
texture_class->download_texture = gdk_gl_texture_download_texture;
|
||||
texture_class->download = gdk_gl_texture_download;
|
||||
texture_class->download_float = gdk_gl_texture_download_float;
|
||||
gobject_class->dispose = gdk_gl_texture_dispose;
|
||||
}
|
||||
|
||||
@@ -150,24 +342,10 @@ gdk_gl_texture_get_id (GdkGLTexture *self)
|
||||
void
|
||||
gdk_gl_texture_release (GdkGLTexture *self)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GdkTexture *texture;
|
||||
cairo_t *cr;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_TEXTURE (self));
|
||||
g_return_if_fail (self->saved == NULL);
|
||||
|
||||
texture = GDK_TEXTURE (self);
|
||||
self->saved = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
texture->width, texture->height);
|
||||
|
||||
cr = cairo_create (self->saved);
|
||||
|
||||
surface = gdk_gl_context_get_surface (self->context);
|
||||
gdk_cairo_draw_from_gl (cr, surface, self->id, GL_TEXTURE, 1, 0, 0,
|
||||
texture->width, texture->height);
|
||||
|
||||
cairo_destroy (cr);
|
||||
self->saved = gdk_texture_download_texture (GDK_TEXTURE (self));
|
||||
|
||||
if (self->destroy)
|
||||
{
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkhslaprivate.h"
|
||||
#include "gdkhslaprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
void
|
||||
_gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
_gdk_hsla_init_from_rgba (GdkHSLA *hsla,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
float min;
|
||||
@@ -31,21 +31,21 @@ _gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
float green;
|
||||
float blue;
|
||||
float delta;
|
||||
|
||||
|
||||
g_return_if_fail (hsla != NULL);
|
||||
g_return_if_fail (rgba != NULL);
|
||||
|
||||
red = rgba->red;
|
||||
green = rgba->green;
|
||||
blue = rgba->blue;
|
||||
|
||||
|
||||
if (red > green)
|
||||
{
|
||||
if (red > blue)
|
||||
max = red;
|
||||
else
|
||||
max = blue;
|
||||
|
||||
|
||||
if (green < blue)
|
||||
min = green;
|
||||
else
|
||||
@@ -57,25 +57,25 @@ _gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
max = green;
|
||||
else
|
||||
max = blue;
|
||||
|
||||
|
||||
if (red < blue)
|
||||
min = red;
|
||||
else
|
||||
min = blue;
|
||||
}
|
||||
|
||||
|
||||
hsla->lightness = (max + min) / 2;
|
||||
hsla->saturation = 0;
|
||||
hsla->hue = 0;
|
||||
hsla->alpha = rgba->alpha;
|
||||
|
||||
|
||||
if (max != min)
|
||||
{
|
||||
if (hsla->lightness <= 0.5)
|
||||
hsla->saturation = (max - min) / (max + min);
|
||||
else
|
||||
hsla->saturation = (max - min) / (2 - max - min);
|
||||
|
||||
|
||||
delta = max -min;
|
||||
if (red == max)
|
||||
hsla->hue = (green - blue) / delta;
|
||||
@@ -83,7 +83,7 @@ _gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
hsla->hue = 2 + (blue - red) / delta;
|
||||
else if (blue == max)
|
||||
hsla->hue = 4 + (red - green) / delta;
|
||||
|
||||
|
||||
hsla->hue *= 60;
|
||||
if (hsla->hue < 0.0)
|
||||
hsla->hue += 360;
|
||||
@@ -92,22 +92,22 @@ _gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
|
||||
void
|
||||
_gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
const GtkHSLA *hsla)
|
||||
const GdkHSLA *hsla)
|
||||
{
|
||||
float hue;
|
||||
float lightness;
|
||||
float saturation;
|
||||
float m1, m2;
|
||||
|
||||
|
||||
lightness = hsla->lightness;
|
||||
saturation = hsla->saturation;
|
||||
|
||||
|
||||
if (lightness <= 0.5)
|
||||
m2 = lightness * (1 + saturation);
|
||||
else
|
||||
m2 = lightness + saturation - lightness * saturation;
|
||||
m1 = 2 * lightness - m2;
|
||||
|
||||
|
||||
rgba->alpha = hsla->alpha;
|
||||
|
||||
if (saturation == 0)
|
||||
@@ -123,7 +123,7 @@ _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
|
||||
|
||||
if (hue < 60)
|
||||
rgba->red = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
@@ -132,13 +132,13 @@ _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
rgba->red = m1;
|
||||
|
||||
|
||||
hue = hsla->hue;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
|
||||
|
||||
if (hue < 60)
|
||||
rgba->green = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
@@ -147,13 +147,13 @@ _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
rgba->green = m1;
|
||||
|
||||
|
||||
hue = hsla->hue - 120;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
|
||||
|
||||
if (hue < 60)
|
||||
rgba->blue = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
@@ -166,8 +166,8 @@ _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_hsla_shade (GtkHSLA *dest,
|
||||
const GtkHSLA *src,
|
||||
_gdk_hsla_shade (GdkHSLA *dest,
|
||||
const GdkHSLA *src,
|
||||
float factor)
|
||||
{
|
||||
g_return_if_fail (dest != NULL);
|
||||
@@ -22,23 +22,23 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkHSLA GtkHSLA;
|
||||
typedef struct _GdkHSLA GdkHSLA;
|
||||
|
||||
struct _GtkHSLA {
|
||||
struct _GdkHSLA {
|
||||
float hue;
|
||||
float saturation;
|
||||
float lightness;
|
||||
float alpha;
|
||||
};
|
||||
|
||||
void _gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
void _gdk_hsla_init_from_rgba (GdkHSLA *hsla,
|
||||
const GdkRGBA *rgba);
|
||||
/* Yes, I can name that function like this! */
|
||||
void _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
const GtkHSLA *hsla);
|
||||
const GdkHSLA *hsla);
|
||||
|
||||
void _gtk_hsla_shade (GtkHSLA *dest,
|
||||
const GtkHSLA *src,
|
||||
void _gdk_hsla_shade (GdkHSLA *dest,
|
||||
const GdkHSLA *src,
|
||||
float factor);
|
||||
|
||||
G_END_DECLS
|
||||
+410
-23
@@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gsk/ngl/fp16private.h"
|
||||
|
||||
/**
|
||||
* GdkMemoryTexture:
|
||||
@@ -49,6 +50,10 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
return 3;
|
||||
|
||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||
@@ -58,9 +63,19 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
return 4;
|
||||
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
return 3;
|
||||
case GDK_MEMORY_R16G16B16:
|
||||
case GDK_MEMORY_R16G16B16_FLOAT:
|
||||
return 6;
|
||||
|
||||
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
|
||||
return 8;
|
||||
|
||||
case GDK_MEMORY_R32G32B32_FLOAT:
|
||||
return 12;
|
||||
|
||||
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
|
||||
return 16;
|
||||
|
||||
case GDK_MEMORY_N_FORMATS:
|
||||
default:
|
||||
@@ -69,6 +84,41 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
|
||||
}
|
||||
}
|
||||
|
||||
static gsize
|
||||
gdk_memory_format_alignment (GdkMemoryFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_B8G8R8A8:
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
return G_ALIGNOF (guchar);
|
||||
|
||||
case GDK_MEMORY_R16G16B16:
|
||||
case GDK_MEMORY_R16G16B16_FLOAT:
|
||||
return G_ALIGNOF (guint16);
|
||||
|
||||
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
|
||||
return G_ALIGNOF (guint16);
|
||||
|
||||
case GDK_MEMORY_R32G32B32_FLOAT:
|
||||
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
|
||||
return G_ALIGNOF (float);
|
||||
|
||||
case GDK_MEMORY_N_FORMATS:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return G_ALIGNOF (double);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_memory_texture_dispose (GObject *object)
|
||||
{
|
||||
@@ -79,22 +129,41 @@ gdk_memory_texture_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (gdk_memory_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
gdk_memory_texture_download_texture (GdkTexture *texture)
|
||||
{
|
||||
return g_object_ref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_memory_texture_download (GdkTexture *texture,
|
||||
const GdkRectangle *area,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
gdk_memory_texture_download (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GdkMemoryTexture *self = GDK_MEMORY_TEXTURE (texture);
|
||||
|
||||
gdk_memory_convert (data, stride,
|
||||
GDK_MEMORY_CAIRO_FORMAT_ARGB32,
|
||||
(guchar *) g_bytes_get_data (self->bytes, NULL)
|
||||
+ area->x * gdk_memory_format_bytes_per_pixel (self->format)
|
||||
+ area->y * self->stride,
|
||||
GDK_MEMORY_CONVERT_DOWNLOAD,
|
||||
(guchar *) g_bytes_get_data (self->bytes, NULL),
|
||||
self->stride,
|
||||
self->format,
|
||||
area->width, area->height);
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_memory_texture_download_float (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride)
|
||||
{
|
||||
GdkMemoryTexture *self = GDK_MEMORY_TEXTURE (texture);
|
||||
|
||||
gdk_memory_convert_to_float (data, stride,
|
||||
(guchar *) g_bytes_get_data (self->bytes, NULL),
|
||||
self->stride,
|
||||
self->format,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -103,7 +172,9 @@ gdk_memory_texture_class_init (GdkMemoryTextureClass *klass)
|
||||
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
texture_class->download_texture = gdk_memory_texture_download_texture;
|
||||
texture_class->download = gdk_memory_texture_download;
|
||||
texture_class->download_float = gdk_memory_texture_download_float;
|
||||
gobject_class->dispose = gdk_memory_texture_dispose;
|
||||
}
|
||||
|
||||
@@ -112,6 +183,41 @@ gdk_memory_texture_init (GdkMemoryTexture *self)
|
||||
{
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
gdk_memory_sanitize (GBytes *bytes,
|
||||
int width,
|
||||
int height,
|
||||
GdkMemoryFormat format,
|
||||
gsize stride,
|
||||
gsize *out_stride)
|
||||
{
|
||||
gsize align, size, copy_stride, bpp;
|
||||
const guchar *data;
|
||||
guchar *copy;
|
||||
int y;
|
||||
|
||||
data = g_bytes_get_data (bytes, &size);
|
||||
align = gdk_memory_format_alignment (format);
|
||||
|
||||
if (GPOINTER_TO_SIZE (data) % align == 0 &&
|
||||
stride % align == 0)
|
||||
{
|
||||
*out_stride = stride;
|
||||
return g_bytes_ref (bytes);
|
||||
}
|
||||
|
||||
bpp = gdk_memory_format_bytes_per_pixel (format);
|
||||
copy_stride = bpp * width;
|
||||
/* align to multiples of 4, just to be sure */
|
||||
copy_stride = (copy_stride + 3) & ~3;
|
||||
copy = g_malloc (copy_stride * height);
|
||||
for (y = 0; y < height; y++)
|
||||
memcpy (copy + y * copy_stride, data + y * stride, bpp * width);
|
||||
|
||||
*out_stride = copy_stride;
|
||||
return g_bytes_new_take (copy, copy_stride * height);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_memory_texture_new:
|
||||
* @width: the width of the texture
|
||||
@@ -136,13 +242,20 @@ gdk_memory_texture_new (int width,
|
||||
{
|
||||
GdkMemoryTexture *self;
|
||||
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
g_return_val_if_fail (stride >= width * gdk_memory_format_bytes_per_pixel (format), NULL);
|
||||
|
||||
bytes = gdk_memory_sanitize (bytes, width, height, format, stride, &stride);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MEMORY_TEXTURE,
|
||||
"width", width,
|
||||
"height", height,
|
||||
NULL);
|
||||
|
||||
self->format = format;
|
||||
self->bytes = g_bytes_ref (bytes);
|
||||
self->bytes = bytes;
|
||||
self->stride = stride;
|
||||
|
||||
return GDK_TEXTURE (self);
|
||||
@@ -283,6 +396,109 @@ SWIZZLE_PREMULTIPLY (3,0,1,2, 0,1,2,3)
|
||||
SWIZZLE_PREMULTIPLY (3,0,1,2, 3,0,1,2)
|
||||
SWIZZLE_PREMULTIPLY (3,0,1,2, 0,3,2,1)
|
||||
|
||||
#define CONVERT_FUNC(name,suffix,R,G,B,A,step) \
|
||||
static void \
|
||||
convert_ ## name ## _to_ ## suffix (guchar *dest_data, \
|
||||
gsize dest_stride, \
|
||||
const guchar *src_data, \
|
||||
gsize src_stride, \
|
||||
gsize width, \
|
||||
gsize height) \
|
||||
{ \
|
||||
gsize x, y; \
|
||||
\
|
||||
for (y = 0; y < height; y++) \
|
||||
{ \
|
||||
for (x = 0; x < width; x++) \
|
||||
{ \
|
||||
guchar conv[4]; \
|
||||
convert_pixel_ ## name (conv, src_data + step * x); \
|
||||
dest_data[4 * x + R] = conv[0]; \
|
||||
dest_data[4 * x + G] = conv[1]; \
|
||||
dest_data[4 * x + B] = conv[2]; \
|
||||
dest_data[4 * x + A] = conv[3]; \
|
||||
} \
|
||||
\
|
||||
dest_data += dest_stride; \
|
||||
src_data += src_stride; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CONVERT_FUNCS(name,step) \
|
||||
CONVERT_FUNC(name, download_le, 2, 1, 0, 3, step) \
|
||||
CONVERT_FUNC(name, download_be, 1, 2, 3, 0, step) \
|
||||
CONVERT_FUNC(name, gles_rgba, 0, 1, 2, 3, step) \
|
||||
|
||||
static inline void
|
||||
convert_pixel_rgb16 (guchar *dest_data, const guchar *src_data)
|
||||
{
|
||||
const guint16 *src = (const guint16 *) src_data;
|
||||
dest_data[0] = (guchar)(src[0] >> 8);
|
||||
dest_data[1] = (guchar)(src[1] >> 8);
|
||||
dest_data[2] = (guchar)(src[2] >> 8);
|
||||
dest_data[3] = 0xFF;
|
||||
}
|
||||
CONVERT_FUNCS(rgb16, 3 * sizeof (guint16))
|
||||
|
||||
static inline void
|
||||
convert_pixel_rgba16 (guchar *dest_data, const guchar *src_data)
|
||||
{
|
||||
const guint16 *src = (const guint16 *) src_data;
|
||||
dest_data[0] = (guchar)(src[0] >> 8);
|
||||
dest_data[1] = (guchar)(src[1] >> 8);
|
||||
dest_data[2] = (guchar)(src[2] >> 8);
|
||||
dest_data[3] = (guchar)(src[3] >> 8);
|
||||
}
|
||||
CONVERT_FUNCS(rgba16, 4 * sizeof (guint16))
|
||||
|
||||
static inline void
|
||||
convert_pixel_rgb16f (guchar *dest_data, const guchar *src_data)
|
||||
{
|
||||
float src[4];
|
||||
guint16 tmp[4];
|
||||
memcpy(tmp, src_data, sizeof(guint16) * 3);
|
||||
half_to_float4(tmp, src);
|
||||
dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
|
||||
dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
|
||||
dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
|
||||
dest_data[3] = 0xFF;
|
||||
}
|
||||
CONVERT_FUNCS(rgb16f, 3 * sizeof (guint16))
|
||||
|
||||
static inline void
|
||||
convert_pixel_rgba16f (guchar *dest_data, const guchar *src_data)
|
||||
{
|
||||
float src[4];
|
||||
half_to_float4((const guint16 *) src_data, src);
|
||||
dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
|
||||
dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
|
||||
dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
|
||||
dest_data[3] = CLAMP (src[3] * 256.f, 0.f, 255.f);
|
||||
}
|
||||
CONVERT_FUNCS(rgba16f, 4 * sizeof (guint16))
|
||||
|
||||
static inline void
|
||||
convert_pixel_rgb32f (guchar *dest_data, const guchar *src_data)
|
||||
{
|
||||
float *src = (float *) src_data;
|
||||
dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
|
||||
dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
|
||||
dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
|
||||
dest_data[3] = 0xFF;
|
||||
}
|
||||
CONVERT_FUNCS(rgb32f, 3 * sizeof (float))
|
||||
|
||||
static inline void
|
||||
convert_pixel_rgba32f (guchar *dest_data, const guchar *src_data)
|
||||
{
|
||||
float *src = (float *) src_data;
|
||||
dest_data[0] = CLAMP (src[0] * 256.f, 0.f, 255.f);
|
||||
dest_data[1] = CLAMP (src[1] * 256.f, 0.f, 255.f);
|
||||
dest_data[2] = CLAMP (src[2] * 256.f, 0.f, 255.f);
|
||||
dest_data[3] = CLAMP (src[3] * 256.f, 0.f, 255.f);
|
||||
}
|
||||
CONVERT_FUNCS(rgba32f, 4 * sizeof (float))
|
||||
|
||||
typedef void (* ConversionFunc) (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
const guchar *src_data,
|
||||
@@ -290,7 +506,7 @@ typedef void (* ConversionFunc) (guchar *dest_data,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
static ConversionFunc converters[GDK_MEMORY_N_FORMATS][3] =
|
||||
static ConversionFunc converters[GDK_MEMORY_N_FORMATS][GDK_MEMORY_N_CONVERSIONS] =
|
||||
{
|
||||
{ convert_memcpy, convert_swizzle3210, convert_swizzle2103 },
|
||||
{ convert_swizzle3210, convert_memcpy, convert_swizzle3012 },
|
||||
@@ -300,21 +516,192 @@ static ConversionFunc converters[GDK_MEMORY_N_FORMATS][3] =
|
||||
{ convert_swizzle_premultiply_3210_3012, convert_swizzle_premultiply_0123_3012, convert_swizzle_premultiply_3012_3012 },
|
||||
{ convert_swizzle_premultiply_3210_0321, convert_swizzle_premultiply_0123_0321, convert_swizzle_premultiply_3012_0321 },
|
||||
{ convert_swizzle_opaque_3210, convert_swizzle_opaque_0123, convert_swizzle_opaque_3012 },
|
||||
{ convert_swizzle_opaque_3012, convert_swizzle_opaque_0321, convert_swizzle_opaque_3210 }
|
||||
{ convert_swizzle_opaque_3012, convert_swizzle_opaque_0321, convert_swizzle_opaque_3210 },
|
||||
{ convert_rgb16_to_download_le, convert_rgb16_to_download_be, convert_rgb16_to_gles_rgba },
|
||||
{ convert_rgba16_to_download_le, convert_rgba16_to_download_be, convert_rgba16_to_gles_rgba },
|
||||
{ convert_rgb16f_to_download_le, convert_rgb16f_to_download_be, convert_rgb16f_to_gles_rgba },
|
||||
{ convert_rgba16f_to_download_le, convert_rgba16f_to_download_be, convert_rgba16f_to_gles_rgba },
|
||||
{ convert_rgb32f_to_download_le, convert_rgb32f_to_download_be, convert_rgb32f_to_gles_rgba },
|
||||
{ convert_rgba32f_to_download_le, convert_rgba32f_to_download_be, convert_rgba32f_to_gles_rgba }
|
||||
};
|
||||
|
||||
void
|
||||
gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryConversion dest_format,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
g_assert (dest_format < 3);
|
||||
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
||||
|
||||
converters[src_format][dest_format] (dest_data, dest_stride, src_data, src_stride, width, height);
|
||||
}
|
||||
|
||||
#define CONVERT_FLOAT(R,G,B,A,premultiply) G_STMT_START {\
|
||||
for (y = 0; y < height; y++) \
|
||||
{ \
|
||||
for (x = 0; x < width; x++) \
|
||||
{ \
|
||||
if (A >= 0) \
|
||||
{ \
|
||||
dest_data[4 * x + 0] = src_data[4 * x + R] / 255.0f; \
|
||||
dest_data[4 * x + 1] = src_data[4 * x + G] / 255.0f; \
|
||||
dest_data[4 * x + 2] = src_data[4 * x + B] / 255.0f; \
|
||||
dest_data[4 * x + 3] = src_data[4 * x + A] / 255.0f; \
|
||||
if (premultiply) \
|
||||
{ \
|
||||
dest_data[4 * x + 0] *= dest_data[4 * x + 3]; \
|
||||
dest_data[4 * x + 1] *= dest_data[4 * x + 3]; \
|
||||
dest_data[4 * x + 2] *= dest_data[4 * x + 3]; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dest_data[4 * x + 0] = src_data[3 * x + R] / 255.0f; \
|
||||
dest_data[4 * x + 1] = src_data[3 * x + G] / 255.0f; \
|
||||
dest_data[4 * x + 2] = src_data[3 * x + B] / 255.0f; \
|
||||
dest_data[4 * x + 3] = 1.0; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
dest_data += dest_stride; \
|
||||
src_data += src_stride; \
|
||||
} \
|
||||
}G_STMT_END
|
||||
|
||||
#define CONVERT_FLOAT_PIXEL(func,step) G_STMT_START{\
|
||||
for (y = 0; y < height; y++) \
|
||||
{ \
|
||||
for (x = 0; x < width; x++) \
|
||||
{ \
|
||||
func (dest_data + 4 * x, src_data + step * x); \
|
||||
} \
|
||||
\
|
||||
dest_data += dest_stride; \
|
||||
src_data += src_stride; \
|
||||
} \
|
||||
}G_STMT_END
|
||||
|
||||
static inline void
|
||||
convert_rgb16_to_float (float *dest, const guchar *src_data)
|
||||
{
|
||||
const guint16 *src = (const guint16 *) src_data;
|
||||
dest[0] = src[0] / 65535.f;
|
||||
dest[1] = src[1] / 65535.f;
|
||||
dest[2] = src[2] / 65535.f;
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
convert_rgba16_to_float (float *dest, const guchar *src_data)
|
||||
{
|
||||
const guint16 *src = (const guint16 *) src_data;
|
||||
dest[0] = src[0] / 65535.f;
|
||||
dest[1] = src[1] / 65535.f;
|
||||
dest[2] = src[2] / 65535.f;
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
convert_rgb16f_to_float (float *dest, const guchar *src_data)
|
||||
{
|
||||
guint16 tmp[4];
|
||||
memcpy(tmp, src_data, sizeof(guint16) * 3);
|
||||
tmp[3] = FP16_ONE;
|
||||
half_to_float4 (tmp, dest);
|
||||
}
|
||||
|
||||
static inline void
|
||||
convert_rgba16f_to_float (float *dest, const guchar *src_data)
|
||||
{
|
||||
half_to_float4 ((const guint16 *) src_data, dest);
|
||||
}
|
||||
|
||||
static inline void
|
||||
convert_rgb32f_to_float (float *dest, const guchar *src_data)
|
||||
{
|
||||
const float *src = (const float *) src_data;
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = 1.0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
convert_rgba32f_to_float (float *dest, const guchar *src_data)
|
||||
{
|
||||
const float *src = (const float *) src_data;
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
}
|
||||
|
||||
void
|
||||
gdk_memory_convert_to_float (float *dest_data,
|
||||
gsize dest_stride,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
gsize x, y;
|
||||
|
||||
switch (src_format)
|
||||
{
|
||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||
CONVERT_FLOAT (2, 1, 0, 3, FALSE);
|
||||
break;
|
||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||
CONVERT_FLOAT (1, 2, 3, 0, FALSE);
|
||||
break;
|
||||
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||
CONVERT_FLOAT (0, 1, 2, 3, FALSE);
|
||||
break;
|
||||
case GDK_MEMORY_B8G8R8A8:
|
||||
CONVERT_FLOAT (2, 1, 0, 3, TRUE);
|
||||
break;
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
CONVERT_FLOAT (1, 2, 3, 0, TRUE);
|
||||
break;
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
CONVERT_FLOAT (0, 1, 2, 3, TRUE);
|
||||
break;
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
CONVERT_FLOAT (3, 2, 1, 0, TRUE);
|
||||
break;
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
CONVERT_FLOAT (0, 1, 2, -1, FALSE);
|
||||
break;
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
CONVERT_FLOAT (2, 1, 0, -1, FALSE);
|
||||
break;
|
||||
case GDK_MEMORY_R16G16B16:
|
||||
CONVERT_FLOAT_PIXEL (convert_rgb16_to_float, 3 * sizeof (guint16));
|
||||
break;
|
||||
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
|
||||
CONVERT_FLOAT_PIXEL (convert_rgba16_to_float, 4 * sizeof (guint16));
|
||||
break;
|
||||
case GDK_MEMORY_R16G16B16_FLOAT:
|
||||
CONVERT_FLOAT_PIXEL (convert_rgb16f_to_float, 3 * sizeof (guint16));
|
||||
break;
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
|
||||
CONVERT_FLOAT_PIXEL (convert_rgba16f_to_float, 4 * sizeof (guint16));
|
||||
break;
|
||||
case GDK_MEMORY_R32G32B32_FLOAT:
|
||||
CONVERT_FLOAT_PIXEL (convert_rgb32f_to_float, 3 * sizeof (float));
|
||||
break;
|
||||
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
|
||||
CONVERT_FLOAT_PIXEL (convert_rgba32f_to_float, 4 * sizeof (float));
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_N_FORMATS:
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,20 @@ G_BEGIN_DECLS
|
||||
* @GDK_MEMORY_A8B8G8R8: 4 bytes; for alpha, blue, green, red.
|
||||
* @GDK_MEMORY_R8G8B8: 3 bytes; for red, green, blue. The data is opaque.
|
||||
* @GDK_MEMORY_B8G8R8: 3 bytes; for blue, green, red. The data is opaque.
|
||||
* @GDK_MEMORY_R16G16B16: 3 guint16 values; for red, green, blue. Since 4.6
|
||||
* @GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: 4 guint16 values; for red, green,
|
||||
* blue, alpha. The color values are premultiplied with the alpha value.
|
||||
* Since 4.6
|
||||
* @GDK_MEMORY_R16G16B16_FLOAT: 3 half-float values; for red, green, blue.
|
||||
* The data is opaque. Since 4.6
|
||||
* @GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: 4 half-float values; for
|
||||
* red, green, blue and alpha. The color values are premultiplied with
|
||||
* the alpha value. Since 4.6
|
||||
* @GDK_MEMORY_B32G32R32_FLOAT: 3 float values; for blue, green, red.
|
||||
* The data is opaque. Since 4.6
|
||||
* @GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED: 4 float values; for
|
||||
* red, green, blue and alpha. The color values are premultiplied with
|
||||
* the alpha value. Since 4.6
|
||||
* @GDK_MEMORY_N_FORMATS: The number of formats. This value will change as
|
||||
* more formats get added, so do not rely on its concrete integer.
|
||||
*
|
||||
@@ -67,6 +81,12 @@ typedef enum {
|
||||
GDK_MEMORY_A8B8G8R8,
|
||||
GDK_MEMORY_R8G8B8,
|
||||
GDK_MEMORY_B8G8R8,
|
||||
GDK_MEMORY_R16G16B16,
|
||||
GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,
|
||||
GDK_MEMORY_R16G16B16_FLOAT,
|
||||
GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED,
|
||||
GDK_MEMORY_R32G32B32_FLOAT,
|
||||
GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
|
||||
|
||||
GDK_MEMORY_N_FORMATS
|
||||
} GdkMemoryFormat;
|
||||
|
||||
@@ -29,7 +29,21 @@ G_BEGIN_DECLS
|
||||
#define GDK_MEMORY_GDK_PIXBUF_OPAQUE GDK_MEMORY_R8G8B8
|
||||
#define GDK_MEMORY_GDK_PIXBUF_ALPHA GDK_MEMORY_R8G8B8A8
|
||||
|
||||
#define GDK_MEMORY_CAIRO_FORMAT_ARGB32 GDK_MEMORY_DEFAULT
|
||||
typedef enum {
|
||||
GDK_MEMORY_CONVERT_DOWNLOAD_LITTLE_ENDIAN,
|
||||
GDK_MEMORY_CONVERT_DOWNLOAD_BIT_ENDIAN,
|
||||
GDK_MEMORY_CONVERT_GLES_RGBA,
|
||||
|
||||
GDK_MEMORY_N_CONVERSIONS
|
||||
} GdkMemoryConversion;
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
#define GDK_MEMORY_CONVERT_DOWNLOAD GDK_MEMORY_CONVERT_DOWNLOAD_LITTLE_ENDIAN
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
#define GDK_MEMORY_CONVERT_DOWNLOAD GDK_MEMORY_CONVERT_DOWNLOAD_BIG_ENDIAN
|
||||
#else
|
||||
#error "Unknown byte order for GDK_MEMORY_CONVERT_DOWNLOAD"
|
||||
#endif
|
||||
|
||||
gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format);
|
||||
|
||||
@@ -37,14 +51,22 @@ GdkMemoryFormat gdk_memory_texture_get_format (GdkMemoryTexture *
|
||||
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
|
||||
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
|
||||
|
||||
void gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height);
|
||||
void gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryConversion dest_format,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
void gdk_memory_convert_to_float (float *dest_data,
|
||||
gsize dest_stride,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+5
-5
@@ -70,17 +70,17 @@ typedef enum {
|
||||
* snapshot at or 0 if none. This is purely a hint. The object must still
|
||||
* be able to render at any size.
|
||||
* @get_intrinsic_aspect_ratio: The preferred aspect ratio for this object
|
||||
* or 0 if none. If both [vfunc@Gdk.PaintableInterface.get_intrinsic_width]
|
||||
* and [vfunc@Gdk.PaintableInterface.get_intrinsic_height] return non-zero
|
||||
* or 0 if none. If both [vfunc@Gdk.Paintable.get_intrinsic_width]
|
||||
* and [vfunc@Gdk.Paintable.get_intrinsic_height] return non-zero
|
||||
* values, this function should return the aspect ratio computed from those.
|
||||
*
|
||||
* The list of functions that can be implemented for the `GdkPaintable`
|
||||
* interface.
|
||||
*
|
||||
* Note that apart from the [vfunc@Gdk.PaintableInterface.snapshot] function,
|
||||
* Note that apart from the [vfunc@Gdk.Paintable.snapshot] function,
|
||||
* no virtual function of this interface is mandatory to implement, though it
|
||||
* is a good idea to implement [vfunc@Gdk.PaintableInterface.get_current_image]
|
||||
* for non-static paintables and [vfunc@Gdk.PaintableInterface.get_flags] if the
|
||||
* is a good idea to implement [vfunc@Gdk.Paintable.get_current_image]
|
||||
* for non-static paintables and [vfunc@Gdk.Paintable.get_flags] if the
|
||||
* image is not dynamic as the default implementation returns no flags and
|
||||
* that will make the implementation likely quite slow.
|
||||
*/
|
||||
|
||||
+86
-4
@@ -30,6 +30,7 @@
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gdkhslaprivate.h"
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GdkRGBA, gdk_rgba,
|
||||
gdk_rgba_copy, gdk_rgba_free)
|
||||
@@ -186,6 +187,7 @@ gdk_rgba_parse (GdkRGBA *rgba,
|
||||
const char *spec)
|
||||
{
|
||||
gboolean has_alpha;
|
||||
gboolean is_hsl;
|
||||
double r, g, b, a;
|
||||
char *str = (char *) spec;
|
||||
char *p;
|
||||
@@ -196,11 +198,26 @@ gdk_rgba_parse (GdkRGBA *rgba,
|
||||
if (strncmp (str, "rgba", 4) == 0)
|
||||
{
|
||||
has_alpha = TRUE;
|
||||
is_hsl = FALSE;
|
||||
str += 4;
|
||||
}
|
||||
else if (strncmp (str, "rgb", 3) == 0)
|
||||
{
|
||||
has_alpha = FALSE;
|
||||
is_hsl = FALSE;
|
||||
a = 1;
|
||||
str += 3;
|
||||
}
|
||||
else if (strncmp (str, "hsla", 4) == 0)
|
||||
{
|
||||
has_alpha = TRUE;
|
||||
is_hsl = TRUE;
|
||||
str += 4;
|
||||
}
|
||||
else if (strncmp (str, "hsl", 3) == 0)
|
||||
{
|
||||
has_alpha = FALSE;
|
||||
is_hsl = TRUE;
|
||||
a = 1;
|
||||
str += 3;
|
||||
}
|
||||
@@ -291,10 +308,22 @@ gdk_rgba_parse (GdkRGBA *rgba,
|
||||
|
||||
if (rgba)
|
||||
{
|
||||
rgba->red = CLAMP (r, 0, 1);
|
||||
rgba->green = CLAMP (g, 0, 1);
|
||||
rgba->blue = CLAMP (b, 0, 1);
|
||||
rgba->alpha = CLAMP (a, 0, 1);
|
||||
if (is_hsl)
|
||||
{
|
||||
GdkHSLA hsla;
|
||||
hsla.hue = r * 255;
|
||||
hsla.saturation = CLAMP (g, 0, 1);
|
||||
hsla.lightness = CLAMP (b, 0, 1);
|
||||
hsla.alpha = CLAMP (a, 0, 1);
|
||||
_gdk_rgba_init_from_hsla (rgba, &hsla);
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba->red = CLAMP (r, 0, 1);
|
||||
rgba->green = CLAMP (g, 0, 1);
|
||||
rgba->blue = CLAMP (b, 0, 1);
|
||||
rgba->alpha = CLAMP (a, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -462,6 +491,47 @@ parse_color_channel (GtkCssParser *parser,
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_hsla_color_channel (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GdkHSLA *hsla = data;
|
||||
double dvalue;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
if (!gtk_css_parser_consume_number (parser, &dvalue))
|
||||
return 0;
|
||||
hsla->hue = dvalue;
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (!gtk_css_parser_consume_percentage (parser, &dvalue))
|
||||
return 0;
|
||||
hsla->saturation = CLAMP (dvalue, 0.0, 100.0) / 100.0;
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
if (!gtk_css_parser_consume_percentage (parser, &dvalue))
|
||||
return 0;
|
||||
hsla->lightness = CLAMP (dvalue, 0.0, 100.0) / 100.0;
|
||||
return 1;
|
||||
|
||||
case 3:
|
||||
if (!gtk_css_parser_consume_number (parser, &dvalue))
|
||||
return 0;
|
||||
|
||||
hsla->alpha = CLAMP (dvalue, 0.0, 1.0) / 1.0;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rgba_init_chars (GdkRGBA *rgba,
|
||||
const char s[8])
|
||||
@@ -501,6 +571,18 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
{
|
||||
return gtk_css_parser_consume_function (parser, 4, 4, parse_color_channel, rgba);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "hsl") || gtk_css_token_is_function (token, "hsla"))
|
||||
{
|
||||
GdkHSLA hsla;
|
||||
|
||||
hsla.alpha = 1.0;
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 3, 4, parse_hsla_color_channel, &hsla))
|
||||
return FALSE;
|
||||
|
||||
_gdk_rgba_init_from_hsla (rgba, &hsla);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
|
||||
{
|
||||
|
||||
+10
-80
@@ -1065,87 +1065,23 @@ gdk_surface_get_mapped (GdkSurface *surface)
|
||||
return GDK_SURFACE_IS_MAPPED (surface);
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_surface_get_shared_data_gl_context (GdkSurface *surface)
|
||||
{
|
||||
static int in_shared_data_creation;
|
||||
GdkDisplay *display;
|
||||
GdkGLContext *context;
|
||||
|
||||
if (in_shared_data_creation)
|
||||
return NULL;
|
||||
|
||||
in_shared_data_creation = 1;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
context = (GdkGLContext *)g_object_get_data (G_OBJECT (display), "gdk-gl-shared-data-context");
|
||||
if (context == NULL)
|
||||
{
|
||||
GError *error = NULL;
|
||||
context = GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface, FALSE, NULL, &error);
|
||||
if (context == NULL)
|
||||
{
|
||||
g_warning ("Failed to create shared context: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
gdk_gl_context_realize (context, &error);
|
||||
if (context == NULL)
|
||||
{
|
||||
g_warning ("Failed to realize shared context: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
|
||||
g_object_set_data (G_OBJECT (display), "gdk-gl-shared-data-context", context);
|
||||
}
|
||||
|
||||
in_shared_data_creation = 0;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
GError **error)
|
||||
GError **error)
|
||||
{
|
||||
GError *internal_error = NULL;
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (surface->display, GL_DISABLE))
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("GL support disabled via GDK_DEBUG"));
|
||||
return NULL;
|
||||
}
|
||||
if (!gdk_display_prepare_gl (surface->display, error))
|
||||
return NULL;
|
||||
|
||||
if (surface->gl_paint_context == NULL)
|
||||
{
|
||||
GdkSurfaceClass *class = GDK_SURFACE_GET_CLASS (surface);
|
||||
|
||||
if (class->create_gl_context == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("The current backend does not support OpenGL"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface->gl_paint_context =
|
||||
class->create_gl_context (surface, TRUE, NULL, &internal_error);
|
||||
surface->gl_paint_context = gdk_surface_create_gl_context (surface, error);
|
||||
if (surface->gl_paint_context == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (internal_error != NULL)
|
||||
if (!gdk_gl_context_realize (surface->gl_paint_context, error))
|
||||
{
|
||||
g_propagate_error (error, internal_error);
|
||||
g_clear_object (&(surface->gl_paint_context));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gdk_gl_context_realize (surface->gl_paint_context, &internal_error);
|
||||
if (internal_error != NULL)
|
||||
{
|
||||
g_propagate_error (error, internal_error);
|
||||
g_clear_object (&(surface->gl_paint_context));
|
||||
g_clear_object (&surface->gl_paint_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1170,19 +1106,13 @@ GdkGLContext *
|
||||
gdk_surface_create_gl_context (GdkSurface *surface,
|
||||
GError **error)
|
||||
{
|
||||
GdkGLContext *paint_context;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
paint_context = gdk_surface_get_paint_gl_context (surface, error);
|
||||
if (paint_context == NULL)
|
||||
if (!gdk_display_prepare_gl (surface->display, error))
|
||||
return NULL;
|
||||
|
||||
return GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface,
|
||||
FALSE,
|
||||
paint_context,
|
||||
error);
|
||||
return gdk_gl_context_new_for_surface (surface);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -160,10 +160,6 @@ struct _GdkSurfaceClass
|
||||
|
||||
void (* set_opaque_region) (GdkSurface *surface,
|
||||
cairo_region_t *region);
|
||||
GdkGLContext *(*create_gl_context) (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
void (* request_layout) (GdkSurface *surface);
|
||||
gboolean (* compute_size) (GdkSurface *surface);
|
||||
};
|
||||
@@ -266,7 +262,6 @@ void _gdk_surface_update_size (GdkSurface *surface);
|
||||
|
||||
GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
|
||||
GError **error);
|
||||
GdkGLContext * gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
|
||||
|
||||
gboolean gdk_surface_handle_event (GdkEvent *event);
|
||||
GdkSeat * gdk_surface_get_seat_from_event (GdkSurface *surface,
|
||||
|
||||
+266
-55
@@ -46,6 +46,11 @@
|
||||
#include "gdksnapshot.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include "loaders/gdkpngprivate.h"
|
||||
#include "loaders/gdktiffprivate.h"
|
||||
#include "loaders/gdkjpegprivate.h"
|
||||
|
||||
G_DEFINE_QUARK (gdk-texture-error-quark, gdk_texture_error)
|
||||
|
||||
/* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */
|
||||
void
|
||||
@@ -115,13 +120,35 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkTexture, gdk_texture, G_TYPE_OBJECT,
|
||||
#define GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD(obj,method) \
|
||||
g_critical ("Texture of type '%s' does not implement GdkTexture::" # method, G_OBJECT_TYPE_NAME (obj))
|
||||
|
||||
static void
|
||||
gdk_texture_real_download (GdkTexture *self,
|
||||
const GdkRectangle *area,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
static GdkTexture *
|
||||
gdk_texture_real_download_texture (GdkTexture *self)
|
||||
{
|
||||
GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (self, download);
|
||||
GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (self, download_texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_texture_real_download (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GdkTexture *memory_texture;
|
||||
|
||||
memory_texture = gdk_texture_download_texture (texture);
|
||||
gdk_texture_download (memory_texture, data, stride);
|
||||
g_object_unref (memory_texture);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_texture_real_download_float (GdkTexture *self,
|
||||
float *data,
|
||||
gsize stride)
|
||||
{
|
||||
GdkTexture *memory_texture;
|
||||
|
||||
memory_texture = gdk_texture_download_texture (self);
|
||||
gdk_texture_download_float (memory_texture, data, stride);
|
||||
g_object_unref (memory_texture);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -187,7 +214,9 @@ gdk_texture_class_init (GdkTextureClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->download_texture = gdk_texture_real_download_texture;
|
||||
klass->download = gdk_texture_real_download;
|
||||
klass->download_float = gdk_texture_real_download_float;
|
||||
|
||||
gobject_class->set_property = gdk_texture_set_property;
|
||||
gobject_class->get_property = gdk_texture_get_property;
|
||||
@@ -263,7 +292,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
|
||||
|
||||
texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
GDK_MEMORY_CAIRO_FORMAT_ARGB32,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
bytes,
|
||||
cairo_image_surface_get_stride (surface));
|
||||
|
||||
@@ -359,28 +388,92 @@ GdkTexture *
|
||||
gdk_texture_new_from_file (GFile *file,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *bytes;
|
||||
GdkTexture *texture;
|
||||
GdkPixbuf *pixbuf;
|
||||
GInputStream *stream;
|
||||
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
stream = G_INPUT_STREAM (g_file_read (file, NULL, error));
|
||||
if (stream == NULL)
|
||||
bytes = g_file_load_bytes (file, NULL, NULL, error);
|
||||
if (bytes == NULL)
|
||||
return NULL;
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error);
|
||||
g_object_unref (stream);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
texture = gdk_texture_new_from_bytes (bytes, error);
|
||||
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_texture_new_from_bytes:
|
||||
* @bytes: a `GBytes` containing the data to load
|
||||
* @error: Return location for an error
|
||||
*
|
||||
* Creates a new texture by loading an image from memory,
|
||||
*
|
||||
* The file format is detected automatically. The supported formats
|
||||
* are PNG and JPEG, though more formats might be available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_texture_new_from_bytes (GBytes *bytes,
|
||||
GError **error)
|
||||
{
|
||||
const char *data;
|
||||
gsize size;
|
||||
|
||||
g_return_val_if_fail (bytes != NULL, NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
data = g_bytes_get_data (bytes, &size);
|
||||
|
||||
if (size > strlen (PNG_SIGNATURE) &&
|
||||
memcmp (data, PNG_SIGNATURE, strlen (PNG_SIGNATURE)) == 0)
|
||||
{
|
||||
return gdk_load_png (bytes, error);
|
||||
}
|
||||
else if ((size > strlen (TIFF_SIGNATURE1) &&
|
||||
memcmp (data, TIFF_SIGNATURE1, strlen (TIFF_SIGNATURE1)) == 0) ||
|
||||
(size > strlen (TIFF_SIGNATURE2) &&
|
||||
memcmp (data, TIFF_SIGNATURE2, strlen (TIFF_SIGNATURE2)) == 0))
|
||||
{
|
||||
return gdk_load_tiff (bytes, error);
|
||||
}
|
||||
else if (size > strlen (JPEG_SIGNATURE) &&
|
||||
memcmp (data, JPEG_SIGNATURE, strlen (JPEG_SIGNATURE)) == 0)
|
||||
{
|
||||
return gdk_load_jpeg (bytes, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
GInputStream *stream;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
stream = g_memory_input_stream_new_from_bytes (bytes);
|
||||
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error);
|
||||
g_object_unref (stream);
|
||||
|
||||
if (pixbuf)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_get_width: (attributes org.gtk.Method.get_property=width)
|
||||
* @texture: a `GdkTexture`
|
||||
@@ -435,20 +528,6 @@ gdk_texture_download_surface (GdkTexture *texture)
|
||||
return surface;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_texture_download_area (GdkTexture *texture,
|
||||
const GdkRectangle *area,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
g_assert (area->x >= 0);
|
||||
g_assert (area->y >= 0);
|
||||
g_assert (area->x + area->width <= texture->width);
|
||||
g_assert (area->y + area->height <= texture->height);
|
||||
|
||||
GDK_TEXTURE_GET_CLASS (texture)->download (texture, area, data, stride);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_download:
|
||||
* @texture: a `GdkTexture`
|
||||
@@ -485,10 +564,62 @@ gdk_texture_download (GdkTexture *texture,
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (stride >= gdk_texture_get_width (texture) * 4);
|
||||
|
||||
gdk_texture_download_area (texture,
|
||||
&(GdkRectangle) { 0, 0, texture->width, texture->height },
|
||||
data,
|
||||
stride);
|
||||
GDK_TEXTURE_GET_CLASS (texture)->download (texture, data, stride);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_download_float:
|
||||
* @texture: a `GdkTexture`
|
||||
* @data: (array): pointer to enough memory to be filled with the
|
||||
* downloaded data of @texture
|
||||
* @stride: rowstride in elements, will usually be equal to
|
||||
* gdk_texture_get_width() * 4
|
||||
*
|
||||
* Downloads the @texture into local memory in a high dynamic range format.
|
||||
*
|
||||
* This may be an expensive operation, as the actual texture data
|
||||
* may reside on a GPU or on a remote display server and because the data
|
||||
* may need to be upsampled if it was not already available in this
|
||||
* format.
|
||||
*
|
||||
* You may want to use [method@Gdk.Texture.download] instead if you don't
|
||||
* need high dynamic range support.
|
||||
*
|
||||
* The data format of the downloaded data is equivalent to
|
||||
* GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, so every downloaded
|
||||
* pixel requires 16 bytes of memory.
|
||||
*
|
||||
* Note that the caller is responsible to provide sufficiently
|
||||
* aligned memory to access the resulting data directly as floats.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
void
|
||||
gdk_texture_download_float (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_TEXTURE (texture));
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (stride >= gdk_texture_get_width (texture) * 4);
|
||||
|
||||
GDK_TEXTURE_GET_CLASS (texture)->download_float (texture, data, stride);
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gdk_texture_download_texture (GdkTexture *texture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
|
||||
|
||||
g_object_ref (texture);
|
||||
while (!GDK_IS_MEMORY_TEXTURE (texture))
|
||||
{
|
||||
GdkTexture *downloaded = GDK_TEXTURE_GET_CLASS (texture)->download_texture (texture);
|
||||
g_object_unref (texture);
|
||||
texture = downloaded;
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -540,7 +671,8 @@ gdk_texture_get_render_data (GdkTexture *self,
|
||||
* This is a utility function intended for debugging and testing.
|
||||
* If you want more control over formats, proper error handling or
|
||||
* want to store to a `GFile` or other location, you might want to
|
||||
* look into using the gdk-pixbuf library.
|
||||
* use gdk_texture_save_to_png_bytes() or look into the
|
||||
* gdk-pixbuf library.
|
||||
*
|
||||
* Returns: %TRUE if saving succeeded, %FALSE on failure.
|
||||
*/
|
||||
@@ -548,30 +680,109 @@ gboolean
|
||||
gdk_texture_save_to_png (GdkTexture *texture,
|
||||
const char *filename)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_status_t status;
|
||||
GBytes *bytes;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
gdk_texture_download (texture,
|
||||
cairo_image_surface_get_data (surface),
|
||||
cairo_image_surface_get_stride (surface));
|
||||
cairo_surface_mark_dirty (surface);
|
||||
|
||||
status = cairo_surface_write_to_png (surface, filename);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS ||
|
||||
cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
|
||||
result = FALSE;
|
||||
else
|
||||
result = TRUE;
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
bytes = gdk_save_png (texture);
|
||||
result = g_file_set_contents (filename,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes),
|
||||
NULL);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_save_to_png_bytes:
|
||||
* @texture: a `GdkTexture`
|
||||
*
|
||||
* Store the given @texture in memory as a PNG file.
|
||||
* Use gdk_texture_new_from_bytes() to read it back.
|
||||
*
|
||||
* If you want to serialize a texture, this is a convenient and
|
||||
* portable way to do that.
|
||||
*
|
||||
* If you need more control over the generated image, such as
|
||||
* attaching metadata, you should look into an image handling
|
||||
* library such as the gdk-pixbuf library.
|
||||
*
|
||||
* If you are dealing with high dynamic range float data, you
|
||||
* might also want to consider gdk_texture_save_to_tiff_bytes()
|
||||
* instead.
|
||||
*
|
||||
* Returns: a newly allocated `GBytes` containing PNG data
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
GBytes *
|
||||
gdk_texture_save_to_png_bytes (GdkTexture *texture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
|
||||
|
||||
return gdk_save_png (texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_save_to_tiff:
|
||||
* @texture: a `GdkTexture`
|
||||
* @filename: (type filename): the filename to store to
|
||||
*
|
||||
* Store the given @texture to the @filename as a TIFF file.
|
||||
*
|
||||
* GTK will attempt to store data without loss.
|
||||
* Returns: %TRUE if saving succeeded, %FALSE on failure.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
gboolean
|
||||
gdk_texture_save_to_tiff (GdkTexture *texture,
|
||||
const char *filename)
|
||||
{
|
||||
GBytes *bytes;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
|
||||
bytes = gdk_save_tiff (texture);
|
||||
result = g_file_set_contents (filename,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes),
|
||||
NULL);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_texture_save_to_tiff_bytes:
|
||||
* @texture: a `GdkTexture`
|
||||
*
|
||||
* Store the given @texture in memory as a TIFF file.
|
||||
* Use gdk_texture_new_from_bytes() to read it back.
|
||||
*
|
||||
* This function is intended to store a representation of the
|
||||
* texture's data that is as accurate as possible. This is
|
||||
* particularly relevant when working with high dynamic range
|
||||
* images and floating-point texture data.
|
||||
*
|
||||
* If that is not your concern and you are interested in a
|
||||
* smaller size and a more portable format, you might want to
|
||||
* use gdk_texture_save_to_png_bytes().
|
||||
*
|
||||
* Returns: a newly allocated `GBytes` containing TIFF data
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
GBytes *
|
||||
gdk_texture_save_to_tiff_bytes (GdkTexture *texture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
|
||||
|
||||
return gdk_save_tiff (texture);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,25 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkTexture, g_object_unref)
|
||||
|
||||
typedef struct _GdkTextureClass GdkTextureClass;
|
||||
|
||||
#define GDK_TEXTURE_ERROR (gdk_texture_error_quark ())
|
||||
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GQuark gdk_texture_error_quark (void);
|
||||
|
||||
/**
|
||||
* GdkTextureError:
|
||||
* @GDK_TEXTURE_ERROR_INSUFFICIENT_MEMORY: Not enough memory to handle this image
|
||||
* @GDK_TEXTURE_ERROR_CORRUPT_IMAGE: The image data appears corrupted
|
||||
* @GDK_TEXTURE_ERROR_UNSUPPORTED: The image format is not supported
|
||||
*
|
||||
* Possible errors that can be returned by `GdkTexture` constructors.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GDK_TEXTURE_ERROR_INSUFFICIENT_MEMORY,
|
||||
GDK_TEXTURE_ERROR_CORRUPT_IMAGE,
|
||||
GDK_TEXTURE_ERROR_UNSUPPORTED,
|
||||
} GdkTextureError;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_texture_get_type (void) G_GNUC_CONST;
|
||||
@@ -49,6 +68,9 @@ GdkTexture * gdk_texture_new_from_resource (const char
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkTexture * gdk_texture_new_from_file (GFile *file,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GdkTexture * gdk_texture_new_from_bytes (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_texture_get_width (GdkTexture *texture) G_GNUC_PURE;
|
||||
@@ -59,9 +81,20 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_texture_download (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
void gdk_texture_download_float (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_texture_save_to_png (GdkTexture *texture,
|
||||
const char *filename);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GBytes * gdk_texture_save_to_png_bytes (GdkTexture *texture);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
gboolean gdk_texture_save_to_tiff (GdkTexture *texture,
|
||||
const char *filename);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GBytes * gdk_texture_save_to_tiff_bytes (GdkTexture *texture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -24,10 +24,15 @@ struct _GdkTexture
|
||||
struct _GdkTextureClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* mandatory: Download into a GdkMemoryTexture */
|
||||
GdkTexture * (* download_texture) (GdkTexture *texture);
|
||||
/* optional */
|
||||
void (* download) (GdkTexture *texture,
|
||||
const GdkRectangle *area,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
void (* download_float) (GdkTexture *texture,
|
||||
float *data,
|
||||
gsize stride);
|
||||
};
|
||||
|
||||
gpointer gdk_texture_new (const GdkTextureClass *klass,
|
||||
@@ -35,10 +40,8 @@ gpointer gdk_texture_new (const GdkTextureClass
|
||||
int height);
|
||||
GdkTexture * gdk_texture_new_for_surface (cairo_surface_t *surface);
|
||||
cairo_surface_t * gdk_texture_download_surface (GdkTexture *texture);
|
||||
void gdk_texture_download_area (GdkTexture *texture,
|
||||
const GdkRectangle *area,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
/* NB: GdkMemoryTexture */
|
||||
GdkTexture * gdk_texture_download_texture (GdkTexture *texture);
|
||||
|
||||
gboolean gdk_texture_set_render_data (GdkTexture *self,
|
||||
gpointer key,
|
||||
|
||||
@@ -78,6 +78,13 @@ gdk_toplevel_default_show_window_menu (GdkToplevel *toplevel,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_toplevel_default_titlebar_gesture (GdkToplevel *toplevel,
|
||||
GdkTitlebarGesture gesture)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_toplevel_default_supports_edge_constraints (GdkToplevel *toplevel)
|
||||
{
|
||||
@@ -114,6 +121,7 @@ gdk_toplevel_default_init (GdkToplevelInterface *iface)
|
||||
iface->supports_edge_constraints = gdk_toplevel_default_supports_edge_constraints;
|
||||
iface->inhibit_system_shortcuts = gdk_toplevel_default_inhibit_system_shortcuts;
|
||||
iface->restore_system_shortcuts = gdk_toplevel_default_restore_system_shortcuts;
|
||||
iface->titlebar_gesture = gdk_toplevel_default_titlebar_gesture;
|
||||
|
||||
/**
|
||||
* GdkToplevel:state: (attributes org.gtk.Property.get=gdk_toplevel_get_state)
|
||||
@@ -716,3 +724,13 @@ gdk_toplevel_begin_move (GdkToplevel *toplevel,
|
||||
x, y,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_toplevel_titlebar_gesture (GdkToplevel *toplevel,
|
||||
GdkTitlebarGesture gesture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
|
||||
|
||||
return GDK_TOPLEVEL_GET_IFACE (toplevel)->titlebar_gesture (toplevel,
|
||||
gesture);
|
||||
}
|
||||
|
||||
@@ -115,6 +115,13 @@ typedef enum
|
||||
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 15
|
||||
} GdkToplevelState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_TITLEBAR_GESTURE_DOUBLE_CLICK = 1,
|
||||
GDK_TITLEBAR_GESTURE_RIGHT_CLICK = 2,
|
||||
GDK_TITLEBAR_GESTURE_MIDDLE_CLICK = 3
|
||||
} GdkTitlebarGesture;
|
||||
|
||||
|
||||
#define GDK_TYPE_TOPLEVEL (gdk_toplevel_get_type ())
|
||||
|
||||
@@ -196,6 +203,10 @@ void gdk_toplevel_begin_move (GdkToplevel *toplevel,
|
||||
double y,
|
||||
guint32 timestamp);
|
||||
|
||||
GDK_AVAILABLE_IN_4_4
|
||||
gboolean gdk_toplevel_titlebar_gesture (GdkToplevel *toplevel,
|
||||
GdkTitlebarGesture gesture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_TOPLEVEL_H__ */
|
||||
|
||||
@@ -38,6 +38,8 @@ struct _GdkToplevelInterface
|
||||
double x,
|
||||
double y,
|
||||
guint32 timestamp);
|
||||
gboolean (* titlebar_gesture) (GdkToplevel *toplevel,
|
||||
GdkTitlebarGesture gesture);
|
||||
};
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -94,6 +94,14 @@
|
||||
*/
|
||||
#define GDK_VERSION_4_4 (G_ENCODE_VERSION (4, 4))
|
||||
|
||||
/**
|
||||
* GDK_VERSION_4_6:
|
||||
*
|
||||
* A macro that evaluates to the 4.6 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*/
|
||||
#define GDK_VERSION_4_6 (G_ENCODE_VERSION (4, 6))
|
||||
|
||||
|
||||
/* evaluates to the current stable version; for development cycles,
|
||||
* this means the next stable target, with a hard backstop to the
|
||||
@@ -221,4 +229,18 @@
|
||||
# define GDK_DEPRECATED_IN_4_4_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_6
|
||||
# define GDK_AVAILABLE_IN_4_6 GDK_UNAVAILABLE(4, 6)
|
||||
#else
|
||||
# define GDK_AVAILABLE_IN_4_6 _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_6
|
||||
# define GDK_DEPRECATED_IN_4_6 GDK_DEPRECATED
|
||||
# define GDK_DEPRECATED_IN_4_6_FOR(f) GDK_DEPRECATED_FOR(f)
|
||||
#else
|
||||
# define GDK_DEPRECATED_IN_4_6 _GDK_EXTERN
|
||||
# define GDK_DEPRECATED_IN_4_6_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#endif /* __GDK_VERSION_MACROS_H__ */
|
||||
|
||||
+39
-39
@@ -117,104 +117,104 @@ gdk_vulkan_strerror (VkResult result)
|
||||
switch (result)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
return "Command successfully completed.";
|
||||
return "Command successfully completed. (VK_SUCCESS)";
|
||||
case VK_NOT_READY:
|
||||
return "A fence or query has not yet completed.";
|
||||
return "A fence or query has not yet completed. (VK_NOT_READY)";
|
||||
case VK_TIMEOUT:
|
||||
return "A wait operation has not completed in the specified time.";
|
||||
return "A wait operation has not completed in the specified time. (VK_TIMEOUT)";
|
||||
case VK_EVENT_SET:
|
||||
return "An event is signaled.";
|
||||
return "An event is signaled. (VK_EVENT_SET)";
|
||||
case VK_EVENT_RESET:
|
||||
return "An event is unsignaled.";
|
||||
return "An event is unsignaled. (VK_EVENT_RESET)";
|
||||
case VK_INCOMPLETE:
|
||||
return "A return array was too small for the result.";
|
||||
return "A return array was too small for the result. (VK_INCOMPLETE)";
|
||||
case VK_SUBOPTIMAL_KHR:
|
||||
return "A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully.";
|
||||
return "A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully. (VK_SUBOPTIMAL_KHR)";
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "A host memory allocation has failed.";
|
||||
return "A host memory allocation has failed. (VK_ERROR_OUT_OF_HOST_MEMORY)";
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "A device memory allocation has failed.";
|
||||
return "A device memory allocation has failed. (VK_ERROR_OUT_OF_DEVICE_MEMORY)";
|
||||
case VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "Initialization of an object could not be completed for implementation-specific reasons.";
|
||||
return "Initialization of an object could not be completed for implementation-specific reasons. (VK_ERROR_INITIALIZATION_FAILED)";
|
||||
case VK_ERROR_DEVICE_LOST:
|
||||
return "The logical or physical device has been lost.";
|
||||
return "The logical or physical device has been lost. (VK_ERROR_DEVICE_LOST)";
|
||||
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "Mapping of a memory object has failed.";
|
||||
return "Mapping of a memory object has failed. (VK_ERROR_MEMORY_MAP_FAILED)";
|
||||
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "A requested layer is not present or could not be loaded.";
|
||||
return "A requested layer is not present or could not be loaded. (VK_ERROR_LAYER_NOT_PRESENT)";
|
||||
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "A requested extension is not supported.";
|
||||
return "A requested extension is not supported. (VK_ERROR_EXTENSION_NOT_PRESENT)";
|
||||
case VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "A requested feature is not supported.";
|
||||
return "A requested feature is not supported. (VK_ERROR_FEATURE_NOT_PRESENT)";
|
||||
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons.";
|
||||
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons. (VK_ERROR_INCOMPATIBLE_DRIVER)";
|
||||
case VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "Too many objects of the type have already been created.";
|
||||
return "Too many objects of the type have already been created. (VK_ERROR_TOO_MANY_OBJECTS)";
|
||||
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "A requested format is not supported on this device.";
|
||||
return "A requested format is not supported on this device. (VK_ERROR_FORMAT_NOT_SUPPORTED)";
|
||||
#if VK_HEADER_VERSION >= 24
|
||||
case VK_ERROR_FRAGMENTED_POOL:
|
||||
return "A requested pool allocation has failed due to fragmentation of the pool’s memory.";
|
||||
return "A requested pool allocation has failed due to fragmentation of the pool’s memory. (VK_ERROR_FRAGMENTED_POOL)";
|
||||
#endif
|
||||
case VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "A surface is no longer available.";
|
||||
return "A surface is no longer available. (VK_ERROR_SURFACE_LOST_KHR)";
|
||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "The requested window is already in use by Vulkan or another API in a manner which prevents it from being used again.";
|
||||
return "The requested window is already in use by Vulkan or another API in a manner which prevents it from being used again. (VK_ERROR_NATIVE_WINDOW_IN_USE_KHR)";
|
||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||
return "A surface has changed in such a way that it is no longer compatible with the swapchain.";
|
||||
return "A surface has changed in such a way that it is no longer compatible with the swapchain. (VK_ERROR_OUT_OF_DATE_KHR)";
|
||||
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an image.";
|
||||
return "The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an image. (VK_ERROR_INCOMPATIBLE_DISPLAY_KHR)";
|
||||
case VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "The application caused the validation layer to fail.";
|
||||
return "The application caused the validation layer to fail. (VK_ERROR_VALIDATION_FAILED_EXT)";
|
||||
case VK_ERROR_INVALID_SHADER_NV:
|
||||
return "One or more shaders failed to compile or link.";
|
||||
return "One or more shaders failed to compile or link. (VK_ERROR_INVALID_SHADER_NV)";
|
||||
#if VK_HEADER_VERSION >= 39
|
||||
case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
|
||||
return "A pool memory allocation has failed.";
|
||||
return "A pool memory allocation has failed. (VK_ERROR_OUT_OF_POOL_MEMORY_KHR)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 54
|
||||
case VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR:
|
||||
return "An external handle is not a valid handle of the specified type.";
|
||||
return "An external handle is not a valid handle of the specified type. (VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 64
|
||||
case VK_ERROR_NOT_PERMITTED_EXT:
|
||||
return "The caller does not have sufficient privileges.";
|
||||
return "The caller does not have sufficient privileges. (VK_ERROR_NOT_PERMITTED_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 72
|
||||
case VK_ERROR_FRAGMENTATION_EXT:
|
||||
return "A descriptor pool creation has failed due to fragmentation";
|
||||
return "A descriptor pool creation has failed due to fragmentation. (VK_ERROR_FRAGMENTATION_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 89
|
||||
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "Invalid DRM format modifier plane layout";
|
||||
return "Invalid DRM format modifier plane layout (VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 97
|
||||
case VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
|
||||
return "Invalid device address";
|
||||
return "Invalid device address (VK_ERROR_INVALID_DEVICE_ADDRESS_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 105
|
||||
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
|
||||
return "An operation on a swapchain created with VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT failed as it did not have exclusive full-screen access.";
|
||||
return "An operation on a swapchain created with VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT failed as it did not have exclusive full-screen access. (VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 131
|
||||
case VK_ERROR_UNKNOWN:
|
||||
return "An unknown error has occurred; either the application has provided invalid input, or an implementation failure has occurred.";
|
||||
return "An unknown error has occurred; either the application has provided invalid input, or an implementation failure has occurred. (VK_ERROR_UNKNOWN)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 135
|
||||
#if VK_HEADER_VERSION < 162
|
||||
case VK_ERROR_INCOMPATIBLE_VERSION_KHR:
|
||||
return "This error was removed by the Vulkan gods.";
|
||||
return "This error was removed by the Vulkan gods. (VK_ERROR_INCOMPATIBLE_VERSION_KHR)";
|
||||
#endif
|
||||
case VK_THREAD_IDLE_KHR:
|
||||
return "A deferred operation is not complete but there is currently no work for this thread to do at the time of this call.";
|
||||
return "A deferred operation is not complete but there is currently no work for this thread to do at the time of this call. (VK_THREAD_IDLE_KHR)";
|
||||
case VK_THREAD_DONE_KHR:
|
||||
return "A deferred operation is not complete but there is no work remaining to assign to additional threads.";
|
||||
return "A deferred operation is not complete but there is no work remaining to assign to additional threads. (VK_THREAD_DONE_KHR)";
|
||||
case VK_OPERATION_DEFERRED_KHR:
|
||||
return "A deferred operation was requested and at least some of the work was deferred.";
|
||||
return "A deferred operation was requested and at least some of the work was deferred. (VK_OPERATION_DEFERRED_KHR)";
|
||||
case VK_OPERATION_NOT_DEFERRED_KHR:
|
||||
return "A deferred operation was requested and no operations were deferred.";
|
||||
return "A deferred operation was requested and no operations were deferred. (VK_OPERATION_NOT_DEFERRED_KHR)";
|
||||
case VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT:
|
||||
return "A requested pipeline creation would have required compilation, but the application requested compilation to not be performed.";
|
||||
return "A requested pipeline creation would have required compilation, but the application requested compilation to not be performed. (VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT)";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION < 140
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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 "gdkjpegprivate.h"
|
||||
|
||||
#include "gdktexture.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/* {{{ Error handling */
|
||||
|
||||
/* No sigsetjmp on Windows */
|
||||
#ifndef HAVE_SIGSETJMP
|
||||
#define sigjmp_buf jmp_buf
|
||||
#define sigsetjmp(jb, x) setjmp(jb)
|
||||
#define siglongjmp longjmp
|
||||
#endif
|
||||
|
||||
struct error_handler_data {
|
||||
struct jpeg_error_mgr pub;
|
||||
sigjmp_buf setjmp_buffer;
|
||||
GError **error;
|
||||
};
|
||||
|
||||
static void
|
||||
fatal_error_handler (j_common_ptr cinfo)
|
||||
{
|
||||
struct error_handler_data *errmgr;
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
errmgr = (struct error_handler_data *) cinfo->err;
|
||||
|
||||
cinfo->err->format_message (cinfo, buffer);
|
||||
|
||||
if (errmgr->error && *errmgr->error == NULL)
|
||||
g_set_error (errmgr->error,
|
||||
GDK_TEXTURE_ERROR,
|
||||
cinfo->err->msg_code == JERR_OUT_OF_MEMORY
|
||||
? GDK_TEXTURE_ERROR_INSUFFICIENT_MEMORY
|
||||
: GDK_TEXTURE_ERROR_CORRUPT_IMAGE,
|
||||
"Error interpreting JPEG image file (%s)", buffer);
|
||||
|
||||
siglongjmp (errmgr->setjmp_buffer, 1);
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static void
|
||||
output_message_handler (j_common_ptr cinfo)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Public API */
|
||||
|
||||
GdkTexture *
|
||||
gdk_load_jpeg (GBytes *input_bytes,
|
||||
GError **error)
|
||||
{
|
||||
struct jpeg_decompress_struct info;
|
||||
struct error_handler_data jerr;
|
||||
struct jpeg_error_mgr err;
|
||||
int width, height;
|
||||
int size;
|
||||
unsigned char *data;
|
||||
unsigned char *row[1];
|
||||
GBytes *bytes;
|
||||
GdkTexture *texture;
|
||||
|
||||
info.err = jpeg_std_error (&jerr.pub);
|
||||
jerr.pub.error_exit = fatal_error_handler;
|
||||
jerr.pub.output_message = output_message_handler;
|
||||
jerr.error = error;
|
||||
|
||||
if (sigsetjmp (jerr.setjmp_buffer, 1))
|
||||
{
|
||||
jpeg_destroy_decompress (&info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info.err = jpeg_std_error (&err);
|
||||
jpeg_create_decompress (&info);
|
||||
|
||||
jpeg_mem_src (&info,
|
||||
g_bytes_get_data (input_bytes, NULL),
|
||||
g_bytes_get_size (input_bytes));
|
||||
|
||||
jpeg_read_header (&info, TRUE);
|
||||
jpeg_start_decompress (&info);
|
||||
|
||||
width = info.output_width;
|
||||
height = info.output_height;
|
||||
|
||||
size = width * height * 3;
|
||||
data = g_try_malloc_n (width * 3, height);
|
||||
if (!data)
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_INSUFFICIENT_MEMORY,
|
||||
"Not enough memory to load jpeg");
|
||||
jpeg_destroy_decompress (&info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (info.output_scanline < info.output_height)
|
||||
{
|
||||
row[0] = (unsigned char *)(&data[3 *info.output_width * info.output_scanline]);
|
||||
jpeg_read_scanlines (&info, row, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress (&info);
|
||||
jpeg_destroy_decompress (&info);
|
||||
|
||||
bytes = g_bytes_new_take (data, size);
|
||||
|
||||
texture = gdk_memory_texture_new (width, height,
|
||||
GDK_MEMORY_R8G8B8,
|
||||
bytes, width * 3);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
@@ -0,0 +1,29 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_JPEG_PRIVATE_H__
|
||||
#define __GDK_JPEG_PRIVATE_H__
|
||||
|
||||
#include "gdkmemorytexture.h"
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define JPEG_SIGNATURE "\xff\xd8"
|
||||
|
||||
GdkTexture *gdk_load_jpeg (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,242 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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 "gdkpngprivate.h"
|
||||
|
||||
#include "gdktexture.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gsk/ngl/fp16private.h"
|
||||
#include <png.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* The main difference between the png load/save code here and
|
||||
* gdk-pixbuf is that we can support loading 16-bit data in the
|
||||
* future, and we can extract gamma and colorspace information
|
||||
* to produce linear, color-corrected data.
|
||||
*/
|
||||
|
||||
/* {{{ Format conversion */
|
||||
|
||||
static void
|
||||
flip_02 (guchar *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
gsize x, y;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
guchar tmp;
|
||||
tmp = data[x * 4];
|
||||
data[x * 4] = data[x * 4 + 2];
|
||||
data[x * 4 + 2] = tmp;
|
||||
}
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_float_to_16bit_inplace (float *src,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
gsize x, y;
|
||||
guint16 *dest = (guint16 *)src;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
dest[4 * x ] = (guint16) CLAMP(65536.f * src[x * 4 ], 0.f, 65535.f);
|
||||
dest[4 * x + 1] = (guint16) CLAMP(65536.f * src[x * 4 + 1], 0.f, 65535.f);
|
||||
dest[4 * x + 2] = (guint16) CLAMP(65536.f * src[x * 4 + 2], 0.f, 65535.f);
|
||||
dest[4 * x + 3] = (guint16) CLAMP(65536.f * src[x * 4 + 3], 0.f, 65535.f);
|
||||
}
|
||||
dest += width * 4;
|
||||
src += width * 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Public API */
|
||||
|
||||
GdkTexture *
|
||||
gdk_load_png (GBytes *bytes,
|
||||
GError **error)
|
||||
{
|
||||
png_image image = { NULL, PNG_IMAGE_VERSION, 0, };
|
||||
gsize size;
|
||||
gsize stride;
|
||||
guchar *buffer;
|
||||
GdkTexture *texture;
|
||||
GBytes *out_bytes;
|
||||
|
||||
png_image_begin_read_from_memory (&image,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes));
|
||||
|
||||
if (PNG_IMAGE_FAILED (image))
|
||||
{
|
||||
g_set_error (error,
|
||||
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED,
|
||||
"Failed to parse png image (%s)", image.message);
|
||||
png_image_free (&image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
|
||||
stride = PNG_IMAGE_ROW_STRIDE (image);
|
||||
size = PNG_IMAGE_BUFFER_SIZE (image, stride);
|
||||
buffer = g_try_malloc (size);
|
||||
if (!buffer)
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_INSUFFICIENT_MEMORY,
|
||||
"Not enough memory to load png");
|
||||
png_image_free (&image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
png_image_finish_read (&image, NULL, buffer, stride, NULL);
|
||||
|
||||
if (PNG_IMAGE_FAILED (image))
|
||||
{
|
||||
g_set_error (error,
|
||||
GDK_TEXTURE_ERROR, GDK_TEXTURE_ERROR_UNSUPPORTED,
|
||||
"Failed to parse png image (%s)", image.message);
|
||||
png_image_free (&image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (image.format & PNG_FORMAT_FLAG_LINEAR)
|
||||
stride *= 2;
|
||||
|
||||
out_bytes = g_bytes_new_take (buffer, size);
|
||||
|
||||
texture = gdk_memory_texture_new (image.width, image.height,
|
||||
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||
out_bytes, stride);
|
||||
|
||||
g_bytes_unref (out_bytes);
|
||||
|
||||
png_image_free (&image);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
GBytes *
|
||||
gdk_save_png (GdkTexture *texture)
|
||||
{
|
||||
png_image image = { NULL, PNG_IMAGE_VERSION, 0, };
|
||||
int stride;
|
||||
const guchar *data;
|
||||
guchar *new_data = NULL;
|
||||
png_alloc_size_t size;
|
||||
gpointer buffer;
|
||||
GdkTexture *memory_texture;
|
||||
GdkMemoryFormat format;
|
||||
gboolean result G_GNUC_UNUSED;
|
||||
|
||||
image.width = gdk_texture_get_width (texture);
|
||||
image.height = gdk_texture_get_height (texture);
|
||||
|
||||
memory_texture = gdk_texture_download_texture (texture);
|
||||
format = gdk_memory_texture_get_format (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||
data = gdk_memory_texture_get_data (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
stride = gdk_memory_texture_get_stride (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_B8G8R8A8:
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
stride = image.width * 4;
|
||||
new_data = g_malloc (stride * image.height);
|
||||
gdk_texture_download (memory_texture, new_data, stride);
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
flip_02 (new_data, image.width, image.height, stride);
|
||||
#endif
|
||||
data = new_data;
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_R16G16B16:
|
||||
data = gdk_memory_texture_get_data (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
stride = gdk_memory_texture_get_stride (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
image.format = PNG_FORMAT_LINEAR_RGB;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
|
||||
data = gdk_memory_texture_get_data (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
stride = gdk_memory_texture_get_stride (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_R16G16B16_FLOAT:
|
||||
case GDK_MEMORY_R32G32B32_FLOAT:
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
|
||||
/* This isn't very efficient */
|
||||
new_data = g_malloc (image.width * image.height * 16);
|
||||
gdk_texture_download_float (memory_texture, (float *)new_data, image.width * 16);
|
||||
convert_float_to_16bit_inplace ((float *)new_data, image.width, image.height);
|
||||
data = new_data;
|
||||
stride = image.width * 8;
|
||||
image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_N_FORMATS:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (image.format & PNG_FORMAT_FLAG_LINEAR)
|
||||
stride /= 2;
|
||||
|
||||
png_image_write_get_memory_size (image, size, FALSE, data, stride, NULL);
|
||||
|
||||
buffer = g_malloc (size);
|
||||
result = png_image_write_to_memory (&image, buffer, &size, FALSE, data, stride, NULL);
|
||||
|
||||
g_assert (result);
|
||||
|
||||
g_object_unref (memory_texture);
|
||||
png_image_free (&image);
|
||||
g_free (new_data);
|
||||
|
||||
return g_bytes_new_take (buffer, size);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
@@ -0,0 +1,31 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_PNG_PRIVATE_H__
|
||||
#define __GDK_PNG_PRIVATE_H__
|
||||
|
||||
#include "gdktexture.h"
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define PNG_SIGNATURE "\x89PNG"
|
||||
|
||||
GdkTexture *gdk_load_png (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
GBytes *gdk_save_png (GdkTexture *texture);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,502 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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 "gdktiffprivate.h"
|
||||
|
||||
#include "gdktexture.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include <tiffio.h>
|
||||
|
||||
/* Our main interest in tiff as an image format is that it is
|
||||
* flexible enough to save all our texture formats without
|
||||
* lossy conversions.
|
||||
*
|
||||
* The loader isn't meant to be a very versatile. It just aims
|
||||
* to load the subset that we're saving ourselves. For anything
|
||||
* else, we fall back to TIFFRGBAImage, which is the same api
|
||||
* that gdk-pixbuf uses.
|
||||
*/
|
||||
|
||||
/* {{{ IO handling */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GBytes **out_bytes;
|
||||
gchar *data;
|
||||
gsize size;
|
||||
gsize position;
|
||||
} TiffIO;
|
||||
|
||||
static void
|
||||
tiff_io_warning (const char *module,
|
||||
const char *fmt,
|
||||
va_list ap) G_GNUC_PRINTF(2, 0);
|
||||
static void
|
||||
tiff_io_warning (const char *module,
|
||||
const char *fmt,
|
||||
va_list ap)
|
||||
{
|
||||
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
|
||||
}
|
||||
|
||||
static void
|
||||
tiff_io_error (const char *module,
|
||||
const char *fmt,
|
||||
va_list ap) G_GNUC_PRINTF(2, 0);
|
||||
static void
|
||||
tiff_io_error (const char *module,
|
||||
const char *fmt,
|
||||
va_list ap)
|
||||
{
|
||||
g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
|
||||
}
|
||||
|
||||
static tsize_t
|
||||
tiff_io_read (thandle_t handle,
|
||||
tdata_t buffer,
|
||||
tsize_t size)
|
||||
{
|
||||
TiffIO *io = (TiffIO *) handle;
|
||||
gsize read;
|
||||
|
||||
read = MIN (size, io->size - io->position);
|
||||
|
||||
memcpy (buffer, io->data + io->position, read);
|
||||
io->position += read;
|
||||
|
||||
return (tsize_t) read;
|
||||
}
|
||||
|
||||
static tsize_t
|
||||
tiff_io_no_write (thandle_t handle,
|
||||
tdata_t buffer,
|
||||
tsize_t size)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (tsize_t) -1;
|
||||
}
|
||||
|
||||
static tsize_t
|
||||
tiff_io_write (thandle_t handle,
|
||||
tdata_t buffer,
|
||||
tsize_t size)
|
||||
{
|
||||
TiffIO *io = (TiffIO *) handle;
|
||||
|
||||
if (io->size - io->position < size)
|
||||
{
|
||||
io->size = io->position + size;
|
||||
io->data = g_realloc (io->data, io->size);
|
||||
}
|
||||
|
||||
memcpy (io->data + io->position, buffer, size);
|
||||
io->position += size;
|
||||
|
||||
return (tsize_t) size;
|
||||
}
|
||||
|
||||
static toff_t
|
||||
tiff_io_seek (thandle_t handle,
|
||||
toff_t offset,
|
||||
int whence)
|
||||
{
|
||||
TiffIO *io = (TiffIO *) handle;
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
case SEEK_SET:
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
offset += io->position;
|
||||
break;
|
||||
case SEEK_END:
|
||||
offset += io->size;
|
||||
break;
|
||||
}
|
||||
if (offset < 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (offset > io->size)
|
||||
{
|
||||
/* Linux apparently can do that */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
io->position = offset;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int
|
||||
tiff_io_close (thandle_t handle)
|
||||
{
|
||||
TiffIO *io = (TiffIO *) handle;
|
||||
|
||||
if (io->out_bytes)
|
||||
*io->out_bytes = g_bytes_new_take (io->data, io->size);
|
||||
|
||||
g_free (io);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static toff_t
|
||||
tiff_io_get_file_size (thandle_t handle)
|
||||
{
|
||||
TiffIO *io = (TiffIO *) handle;
|
||||
|
||||
return io->size;
|
||||
}
|
||||
|
||||
static TIFF *
|
||||
tiff_open_read (GBytes *bytes)
|
||||
{
|
||||
TiffIO *io;
|
||||
|
||||
TIFFSetWarningHandler ((TIFFErrorHandler) tiff_io_warning);
|
||||
TIFFSetErrorHandler ((TIFFErrorHandler) tiff_io_error);
|
||||
|
||||
io = g_new0 (TiffIO, 1);
|
||||
|
||||
io->data = (char *) g_bytes_get_data (bytes, &io->size);
|
||||
|
||||
return TIFFClientOpen ("GTK-read", "r",
|
||||
(thandle_t) io,
|
||||
tiff_io_read,
|
||||
tiff_io_no_write,
|
||||
tiff_io_seek,
|
||||
tiff_io_close,
|
||||
tiff_io_get_file_size,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static TIFF *
|
||||
tiff_open_write (GBytes **result)
|
||||
{
|
||||
TiffIO *io;
|
||||
|
||||
TIFFSetWarningHandler ((TIFFErrorHandler) tiff_io_warning);
|
||||
TIFFSetErrorHandler ((TIFFErrorHandler) tiff_io_error);
|
||||
|
||||
io = g_new0 (TiffIO, 1);
|
||||
|
||||
io->out_bytes = result;
|
||||
|
||||
return TIFFClientOpen ("GTK-write", "w",
|
||||
(thandle_t) io,
|
||||
tiff_io_read,
|
||||
tiff_io_write,
|
||||
tiff_io_seek,
|
||||
tiff_io_close,
|
||||
tiff_io_get_file_size,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Format conversion */
|
||||
|
||||
static void
|
||||
flip_02 (guchar *data,
|
||||
int width,
|
||||
int height,
|
||||
int stride)
|
||||
{
|
||||
gsize x, y;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
guchar tmp;
|
||||
tmp = data[x * 4];
|
||||
data[x * 4] = data[x * 4 + 2];
|
||||
data[x * 4 + 2] = tmp;
|
||||
}
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Public API */
|
||||
|
||||
static struct {
|
||||
GdkMemoryFormat format;
|
||||
guint16 bits_per_sample;
|
||||
guint16 samples_per_pixel;
|
||||
guint16 sample_format;
|
||||
} format_data[] = {
|
||||
{ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT },
|
||||
{ GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT },
|
||||
{ GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT },
|
||||
{ GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT },
|
||||
{ GDK_MEMORY_R16G16B16_FLOAT, 16, 3, SAMPLEFORMAT_IEEEFP },
|
||||
{ GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_IEEEFP },
|
||||
{ GDK_MEMORY_R32G32B32_FLOAT, 32, 3, SAMPLEFORMAT_IEEEFP },
|
||||
{ GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, 32, 4, SAMPLEFORMAT_IEEEFP },
|
||||
};
|
||||
|
||||
GBytes *
|
||||
gdk_save_tiff (GdkTexture *texture)
|
||||
{
|
||||
TIFF *tif;
|
||||
int width, height, stride;
|
||||
guint16 bits_per_sample = 0;
|
||||
guint16 samples_per_pixel = 0;
|
||||
guint16 sample_format = 0;
|
||||
const guchar *line;
|
||||
const guchar *data;
|
||||
guchar *new_data = NULL;
|
||||
GBytes *result = NULL;
|
||||
GdkTexture *memory_texture;
|
||||
GdkMemoryFormat format;
|
||||
|
||||
tif = tiff_open_write (&result);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
|
||||
memory_texture = gdk_texture_download_texture (texture);
|
||||
format = gdk_memory_texture_get_format (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
|
||||
for (int i = 0; i < G_N_ELEMENTS (format_data); i++)
|
||||
{
|
||||
if (format == format_data[i].format)
|
||||
{
|
||||
data = gdk_memory_texture_get_data (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
stride = gdk_memory_texture_get_stride (GDK_MEMORY_TEXTURE (memory_texture));
|
||||
bits_per_sample = format_data[i].bits_per_sample;
|
||||
samples_per_pixel = format_data[i].samples_per_pixel;
|
||||
sample_format = format_data[i].sample_format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits_per_sample == 0)
|
||||
{
|
||||
/* An 8-bit format we don't have in the table, handle
|
||||
* it by converting to R8G8B8A8_PREMULTIPLIED
|
||||
*/
|
||||
stride = width * 4;
|
||||
new_data = g_malloc (stride * height);
|
||||
gdk_texture_download (memory_texture, new_data, stride);
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
flip_02 (new_data, width, height, stride);
|
||||
#endif
|
||||
data = new_data;
|
||||
bits_per_sample = 8;
|
||||
samples_per_pixel = 4;
|
||||
sample_format = SAMPLEFORMAT_UINT;
|
||||
}
|
||||
|
||||
TIFFSetField (tif, TIFFTAG_SOFTWARE, "GTK");
|
||||
TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, width);
|
||||
TIFFSetField (tif, TIFFTAG_IMAGELENGTH, height);
|
||||
TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
|
||||
TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel);
|
||||
TIFFSetField (tif, TIFFTAG_SAMPLEFORMAT, sample_format);
|
||||
TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||||
TIFFSetField (tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
|
||||
// TODO: save gamma / colorspace
|
||||
|
||||
if (samples_per_pixel > 3)
|
||||
{
|
||||
guint16 extra_samples[] = { EXTRASAMPLE_ASSOCALPHA };
|
||||
TIFFSetField (tif, TIFFTAG_EXTRASAMPLES, 1, extra_samples);
|
||||
}
|
||||
|
||||
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||
|
||||
line = (const guchar *)data;
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
if (TIFFWriteScanline (tif, (void *)line, y, 0) == -1)
|
||||
{
|
||||
TIFFClose (tif);
|
||||
g_free (new_data);
|
||||
g_object_unref (memory_texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line += stride;
|
||||
}
|
||||
|
||||
TIFFFlushData (tif);
|
||||
TIFFClose (tif);
|
||||
|
||||
g_assert (result);
|
||||
|
||||
g_free (new_data);
|
||||
g_object_unref (memory_texture);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
load_fallback (TIFF *tif,
|
||||
GError **error)
|
||||
{
|
||||
int width, height;
|
||||
guchar *data;
|
||||
GBytes *bytes;
|
||||
GdkTexture *texture;
|
||||
|
||||
TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &width);
|
||||
TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &height);
|
||||
|
||||
data = g_malloc (width * height * 4);
|
||||
|
||||
if (!TIFFReadRGBAImageOriented (tif, width, height, (uint32 *)data, ORIENTATION_TOPLEFT, 1))
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Failed to load RGB data from TIFF file");
|
||||
g_free (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes = g_bytes_new_take (data, width * height * 4);
|
||||
|
||||
texture = gdk_memory_texture_new (width, height,
|
||||
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
|
||||
bytes,
|
||||
width * 4);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gdk_load_tiff (GBytes *input_bytes,
|
||||
GError **error)
|
||||
{
|
||||
TIFF *tif;
|
||||
guint16 samples_per_pixel;
|
||||
guint16 bits_per_sample;
|
||||
guint16 photometric;
|
||||
guint16 planarconfig;
|
||||
guint16 sample_format;
|
||||
guint16 orientation;
|
||||
guint32 width, height;
|
||||
GdkMemoryFormat format;
|
||||
guchar *data, *line;
|
||||
gsize stride;
|
||||
int bpp;
|
||||
GBytes *bytes;
|
||||
GdkTexture *texture;
|
||||
|
||||
tif = tiff_open_read (input_bytes);
|
||||
|
||||
TIFFSetDirectory (tif, 0);
|
||||
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_SAMPLEFORMAT, &sample_format);
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_PHOTOMETRIC, &photometric);
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_PLANARCONFIG, &planarconfig);
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation);
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_IMAGEWIDTH, &width);
|
||||
TIFFGetFieldDefaulted (tif, TIFFTAG_IMAGELENGTH, &height);
|
||||
|
||||
if (samples_per_pixel == 4)
|
||||
{
|
||||
guint16 extra;
|
||||
guint16 *extra_types;
|
||||
|
||||
if (!TIFFGetField (tif, TIFFTAG_EXTRASAMPLES, &extra, &extra_types))
|
||||
extra = 0;
|
||||
|
||||
if (extra == 0 || extra_types[0] != EXTRASAMPLE_ASSOCALPHA)
|
||||
{
|
||||
texture = load_fallback (tif, error);
|
||||
TIFFClose (tif);
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
|
||||
format = 0;
|
||||
|
||||
for (int i = 0; i < G_N_ELEMENTS (format_data); i++)
|
||||
{
|
||||
if (format_data[i].sample_format == sample_format &&
|
||||
format_data[i].bits_per_sample == bits_per_sample &&
|
||||
format_data[i].samples_per_pixel == samples_per_pixel)
|
||||
{
|
||||
format = format_data[i].format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (format == 0 ||
|
||||
photometric != PHOTOMETRIC_RGB ||
|
||||
planarconfig != PLANARCONFIG_CONTIG ||
|
||||
TIFFIsTiled (tif) ||
|
||||
orientation != ORIENTATION_TOPLEFT)
|
||||
{
|
||||
texture = load_fallback (tif, error);
|
||||
TIFFClose (tif);
|
||||
return texture;
|
||||
}
|
||||
|
||||
stride = width * gdk_memory_format_bytes_per_pixel (format);
|
||||
|
||||
g_assert (TIFFScanlineSize (tif) == stride);
|
||||
|
||||
data = g_new (guchar, height * stride);
|
||||
|
||||
line = data;
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
if (TIFFReadScanline (tif, line, y, 0) == -1)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Reading data failed at row %d", y);
|
||||
TIFFClose (tif);
|
||||
g_free (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line += stride;
|
||||
}
|
||||
|
||||
bpp = gdk_memory_format_bytes_per_pixel (format);
|
||||
bytes = g_bytes_new_take (data, width * height * bpp);
|
||||
|
||||
texture = gdk_memory_texture_new (width, height,
|
||||
format,
|
||||
bytes, width * bpp);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
TIFFClose (tif);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
@@ -0,0 +1,32 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_TIFF_PRIVATE_H__
|
||||
#define __GDK_TIFF_PRIVATE_H__
|
||||
|
||||
#include "gdktexture.h"
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define TIFF_SIGNATURE1 "MM\x00\x2a"
|
||||
#define TIFF_SIGNATURE2 "II\x2a\x00"
|
||||
|
||||
GdkTexture *gdk_load_tiff (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
GBytes * gdk_save_tiff (GdkTexture *texture);
|
||||
|
||||
#endif
|
||||
@@ -197,7 +197,7 @@ gdk_display_link_source_new (void)
|
||||
gdk_display_link_source_frame_cb,
|
||||
source);
|
||||
|
||||
g_source_set_name (source, "[gdk] quartz frame clock");
|
||||
g_source_set_static_name (source, "[gdk] quartz frame clock");
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -637,17 +637,13 @@ gdk_macos_display_load_clipboard (GdkMacosDisplay *self)
|
||||
GDK_DISPLAY (self)->clipboard = _gdk_macos_clipboard_new (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *gl_context)
|
||||
static GdkGLContext *
|
||||
gdk_macos_display_init_gl (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
||||
g_assert (!gl_context || GDK_IS_MACOS_GL_CONTEXT (gl_context));
|
||||
|
||||
if (gl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
return _gdk_macos_gl_context_make_current (GDK_MACOS_GL_CONTEXT (gl_context));
|
||||
return g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -695,7 +691,7 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
|
||||
display_class->get_name = gdk_macos_display_get_name;
|
||||
display_class->get_setting = gdk_macos_display_get_setting;
|
||||
display_class->has_pending = gdk_macos_display_has_pending;
|
||||
display_class->make_gl_context_current = gdk_macos_display_make_gl_context_current;
|
||||
display_class->init_gl = gdk_macos_display_init_gl;
|
||||
display_class->notify_startup_complete = gdk_macos_display_notify_startup_complete;
|
||||
display_class->queue_events = gdk_macos_display_queue_events;
|
||||
display_class->sync = gdk_macos_display_sync;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include "gdkmacosdevice-private.h"
|
||||
#include "gdkmacoscursor-private.h"
|
||||
@@ -161,7 +162,7 @@ gdk_macos_drag_drop_done (GdkDrag *drag,
|
||||
gdk_macos_zoomback_timeout,
|
||||
zb,
|
||||
(GDestroyNotify) gdk_macos_zoomback_destroy);
|
||||
g_source_set_name_by_id (id, "[gtk] gdk_macos_zoomback_timeout");
|
||||
gdk_source_set_static_name_by_id (id, "[gtk] gdk_macos_zoomback_timeout");
|
||||
g_object_unref (drag);
|
||||
}
|
||||
|
||||
@@ -242,9 +243,11 @@ gdk_macos_drag_drop_performed (GdkDrag *drag,
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
g_object_ref (self);
|
||||
drag_ungrab (self);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
|
||||
#include "gdk-private.h"
|
||||
|
||||
/*
|
||||
* This file implementations integration between the GLib main loop and
|
||||
* the native system of the Core Foundation run loop and Cocoa event
|
||||
@@ -1063,7 +1065,7 @@ _gdk_macos_event_source_new (GdkMacosDisplay *display)
|
||||
event_poll_fd.fd = -1;
|
||||
|
||||
source = g_source_new (&event_funcs, sizeof (GdkMacosEventSource));
|
||||
g_source_set_name (source, "GDK Quartz event source");
|
||||
g_source_set_static_name (source, "GDK Quartz event source");
|
||||
g_source_add_poll (source, &event_poll_fd);
|
||||
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
|
||||
g_source_set_can_recurse (source, TRUE);
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
#ifndef __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||
#define __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||
|
||||
#include "gdkmacosglcontext.h"
|
||||
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#include "gdkmacosglcontext.h"
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
@@ -55,11 +57,6 @@ struct _GdkMacosGLContextClass
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
|
||||
GdkGLContext *_gdk_macos_gl_context_new (GdkMacosSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gboolean _gdk_macos_gl_context_make_current (GdkMacosGLContext *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -170,12 +170,12 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
{
|
||||
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
|
||||
GdkSurface *surface;
|
||||
GdkDisplay *display;
|
||||
NSOpenGLContext *shared_gl_context = nil;
|
||||
NSOpenGLContext *gl_context;
|
||||
NSOpenGLPixelFormat *pixelFormat;
|
||||
CGLContextObj cgl_context;
|
||||
GdkGLContext *shared;
|
||||
GdkGLContext *shared_data;
|
||||
NSOpenGLContext *existing;
|
||||
GLint sync_to_framerate = 1;
|
||||
GLint validate = 0;
|
||||
@@ -192,21 +192,16 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
|
||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
shared = gdk_gl_context_get_shared_context (context);
|
||||
shared_data = gdk_surface_get_shared_data_gl_context (surface);
|
||||
display = gdk_gl_context_get_display (context);
|
||||
shared = gdk_display_get_gl_context (display);
|
||||
|
||||
if (shared != NULL)
|
||||
{
|
||||
if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
|
||||
return FALSE;
|
||||
}
|
||||
else if (shared_data != NULL)
|
||||
{
|
||||
if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared_data), error)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
|
||||
GDK_DISPLAY_NOTE (display,
|
||||
OPENGL,
|
||||
g_message ("Creating NSOpenGLContext (version %d.%d)",
|
||||
major, minor));
|
||||
@@ -253,7 +248,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
|
||||
|
||||
GLint renderer_id = 0;
|
||||
[gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
|
||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
|
||||
GDK_DISPLAY_NOTE (display,
|
||||
OPENGL,
|
||||
g_message ("Created NSOpenGLContext[%p] using %s",
|
||||
gl_context,
|
||||
@@ -315,9 +310,7 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
* want to replace our damage region for the next frame (to avoid
|
||||
* doing it multiple times).
|
||||
*/
|
||||
if (!self->is_attached &&
|
||||
gdk_gl_context_get_shared_context (GDK_GL_CONTEXT (context)))
|
||||
ensure_gl_view (self);
|
||||
ensure_gl_view (self);
|
||||
|
||||
if (self->needs_resize)
|
||||
{
|
||||
@@ -410,6 +403,57 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context == current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context != current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[self->gl_context makeCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_macos_gl_context_get_damage (GdkGLContext *context)
|
||||
{
|
||||
@@ -478,52 +522,4 @@ gdk_macos_gl_context_init (GdkMacosGLContext *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
_gdk_macos_gl_context_new (GdkMacosSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkMacosGLContext *context;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (surface), NULL);
|
||||
g_return_val_if_fail (!share || GDK_IS_MACOS_GL_CONTEXT (share), NULL);
|
||||
|
||||
context = g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||
"surface", surface,
|
||||
"shared-context", share,
|
||||
NULL);
|
||||
|
||||
context->is_attached = !!attached;
|
||||
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_gl_context_make_current (GdkMacosGLContext *self)
|
||||
{
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
if (self->gl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context != current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[self->gl_context makeCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
@@ -358,20 +358,6 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
return GDK_DRAG (g_steal_pointer (&drag));
|
||||
}
|
||||
|
||||
static GdkGLContext *
|
||||
gdk_macos_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkMacosSurface *self = (GdkMacosSurface *)surface;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
g_assert (!share || GDK_IS_GL_CONTEXT (share));
|
||||
|
||||
return _gdk_macos_gl_context_new (self, attached, share, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy)
|
||||
@@ -495,7 +481,6 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
|
||||
object_class->get_property = gdk_macos_surface_get_property;
|
||||
object_class->set_property = gdk_macos_surface_set_property;
|
||||
|
||||
surface_class->create_gl_context = gdk_macos_surface_create_gl_context;
|
||||
surface_class->destroy = gdk_macos_surface_destroy;
|
||||
surface_class->drag_begin = gdk_macos_surface_drag_begin;
|
||||
surface_class->get_device_state = gdk_macos_surface_get_device_state;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user