Compare commits
506 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 989553758e | |||
| 767df50eda | |||
| baae2920dc | |||
| 832419b2c3 | |||
| ff78adb25d | |||
| e05f404fc5 | |||
| d572b5d94c | |||
| c2306d3ba6 | |||
| edf56b438e | |||
| cd3cd64769 | |||
| fb0b0ddfe0 | |||
| 3180cdb9ef | |||
| 07d1ea4356 | |||
| e5f1ff6a4d | |||
| f8303c7a22 | |||
| af6d1839e1 | |||
| b4b7fe122e | |||
| e36940fa8c | |||
| d2e13dd3e4 | |||
| ad48bbb849 | |||
| 2497d982b0 | |||
| ace2208f45 | |||
| b8c4009686 | |||
| 6f0ff3a8cb | |||
| 209e8b54e9 | |||
| 07d17c5bc1 | |||
| e26c361d2d | |||
| 290e250886 | |||
| 22d5b9bc41 | |||
| ab407ba57c | |||
| 07f2024bfc | |||
| accbfc0083 | |||
| e8d890ae0c | |||
| bfc1e77b7f | |||
| dba9298c14 | |||
| 67c0f88c00 | |||
| e93408e962 | |||
| 6d193d7cb4 | |||
| fb4fbfb2a8 | |||
| 7e77afe94c | |||
| 7587996279 | |||
| 15b3c0f563 | |||
| 5e341210a1 | |||
| fbea677a5c | |||
| b271db4f5b | |||
| b5ed2d310e | |||
| 3bf9277de6 | |||
| 53c9eb5a5b | |||
| 6e5da14294 | |||
| 427b5d187c | |||
| 5d07877b35 | |||
| 3086715d54 | |||
| 44093f4966 | |||
| 6d16f7ad35 | |||
| 5f627a2cb6 | |||
| 34d002121d | |||
| 22bb1bd568 | |||
| 28898445ff | |||
| 828b58247c | |||
| de29c3e193 | |||
| 8ccf2a722a | |||
| fa8ce17e1e | |||
| 4a2f3130d2 | |||
| eaa6301e53 | |||
| 41c52e955d | |||
| eca7fa075e | |||
| 19a4e76034 | |||
| 6cacff9df1 | |||
| 2d309725c9 | |||
| a5c00685c5 | |||
| 48cc26246f | |||
| 4b41dd4eb1 | |||
| 41beae1956 | |||
| c48fe6d7ec | |||
| a31a80277c | |||
| 745a701b3d | |||
| d4c97ea2b4 | |||
| 03738634ac | |||
| 9dd8652a66 | |||
| cb81a06793 | |||
| 4d9cc483c9 | |||
| 4cca27a7af | |||
| 553a9c292d | |||
| abd4754648 | |||
| e79d585b00 | |||
| 1f0310ddff | |||
| 0284d40e24 | |||
| ffaf26fdf5 | |||
| 5b508ea94a | |||
| 472d8eebbe | |||
| dd316c8051 | |||
| 1038bc781a | |||
| 44137574a1 | |||
| 6b07ce2b13 | |||
| 008e8076a1 | |||
| 2cd4b255cd | |||
| 11a38dd455 | |||
| dfcc40ef9a | |||
| 1882034323 | |||
| aaaa3e141b | |||
| 15af87345d | |||
| 640db05b18 | |||
| 31ae93475d | |||
| 8fc4d229da | |||
| a62efb8257 | |||
| acf927fe14 | |||
| ca71340c6b | |||
| 350495cf1c | |||
| 426d5ca1b7 | |||
| aaae141687 | |||
| 4826255ea3 | |||
| 9ba08a09cb | |||
| bb2c68452c | |||
| 23be10cf69 | |||
| 17a111968b | |||
| d3431f569c | |||
| 7a73f43de3 | |||
| ba7649b388 | |||
| 1dd55ed600 | |||
| 416b2cd18d | |||
| 15dffb47dc | |||
| 20e70a78c4 | |||
| e190b4536a | |||
| 3c219bf968 | |||
| c3de5e3624 | |||
| dd69bcabf7 | |||
| 6373ced608 | |||
| 2ea95a7674 | |||
| dbbb7eef15 | |||
| 233d096261 | |||
| 239c178ef4 | |||
| fdbb925654 | |||
| aeabe3c40e | |||
| 222b6c2b58 | |||
| 5ab5ff7677 | |||
| 8a603ff5bd | |||
| 468295a9f7 | |||
| 6c92b824f3 | |||
| 77e9788517 | |||
| 0b1845b0cb | |||
| 342d88a1dc | |||
| bab7f56f64 | |||
| 9b87cace47 | |||
| c2a32afe97 | |||
| d0e14f79a6 | |||
| 7f2ab0d576 | |||
| d36d7d93e6 | |||
| d777300d4e | |||
| 173bb2e1e8 | |||
| 0895f0211e | |||
| be13a23722 | |||
| 7197743938 | |||
| dd5ee87b5b | |||
| e34d1b8a26 | |||
| c5af463843 | |||
| 49748c9c23 | |||
| b53fa48794 | |||
| 97f3371709 | |||
| 58d57e1087 | |||
| 571068af12 | |||
| a00d12c62a | |||
| 7fc74eaeae | |||
| 4eb077979f | |||
| 9c1b1eb894 | |||
| 14c34a7014 | |||
| 427deb4f13 | |||
| a1a70a1130 | |||
| 19304c1d2c | |||
| 01be7f0666 | |||
| 1b68e76852 | |||
| 9f5ee77a44 | |||
| 6d20fe0bf9 | |||
| bb56b4ef5d | |||
| 5ea21f7910 | |||
| acb7f437fa | |||
| 7bff3abe8e | |||
| e46a7ca706 | |||
| e9ba7eda47 | |||
| 88649b6aae | |||
| 60d63bbada | |||
| b8f62d1e10 | |||
| 989307e4c2 | |||
| 7344723a95 | |||
| 4c4bca0c39 | |||
| d570121704 | |||
| 93122ac935 | |||
| f9e100cb1e | |||
| d3ad178d95 | |||
| 123cbd42bb | |||
| 977ac2b31f | |||
| bcdc3b706c | |||
| 61db797f29 | |||
| 0a876f11a0 | |||
| 019e3c02ed | |||
| 1c17316f9c | |||
| 646c5f369f | |||
| 8839e10d44 | |||
| 9b61bfb3c8 | |||
| 60e2242256 | |||
| 4f5a9be465 | |||
| 6a4c778791 | |||
| 1caa95b814 | |||
| cf44ba7847 | |||
| 30433d7659 | |||
| 849b950763 | |||
| 8937cd992d | |||
| e296c6a356 | |||
| 136400e8a2 | |||
| 90199534e0 | |||
| f7c64b4ebb | |||
| f4f060c843 | |||
| 2977e91aed | |||
| 0b999c73d1 | |||
| 9b1e0dd4a3 | |||
| a29826bb71 | |||
| a181136646 | |||
| 5b04201da8 | |||
| 528297f5e5 | |||
| b29feb193e | |||
| 75b5c2a293 | |||
| e32c992886 | |||
| c7a5d99286 | |||
| c9ca60c201 | |||
| d9f6f26cd8 | |||
| e4a00f864d | |||
| 329f7c1c40 | |||
| c23afb2c86 | |||
| e838ea3bc8 | |||
| e5de03144f | |||
| e325f65c8a | |||
| 2a40ff1b47 | |||
| 371c325ed1 | |||
| 542b95e7e8 | |||
| 3d3525a589 | |||
| 553c458e5a | |||
| 7cdb8d8565 | |||
| 172f68e77d | |||
| fb1145d72d | |||
| bd9687a4f2 | |||
| 8928323c6b | |||
| c7203550a2 | |||
| 49887d4c81 | |||
| d8c940325c | |||
| 3944d64d08 | |||
| e20f547317 | |||
| a3cef6c05e | |||
| 11ee72fc7e | |||
| bcd8941769 | |||
| 355d3f070a | |||
| b5b81dea7f | |||
| 5803366f7d | |||
| d3fc47e149 | |||
| b8f37da911 | |||
| 722f8e825e | |||
| a743412c58 | |||
| a6f14555d1 | |||
| 1c091a03f3 | |||
| 2dfb8de0ec | |||
| 876e256f94 | |||
| eb834b8370 | |||
| dbabdf8341 | |||
| 703fda3be8 | |||
| 2f6d6f2473 | |||
| 3f3c8436c5 | |||
| d8b0a78c1e | |||
| 013538daf9 | |||
| 919d823311 | |||
| 075c77325b | |||
| 5f8dc5459e | |||
| adff8c2c60 | |||
| 3b959456ac | |||
| 47ef5af778 | |||
| 76ea157f17 | |||
| f354a7787a | |||
| 83eeeb6a19 | |||
| 6db181980a | |||
| 023bb2c984 | |||
| a3cfb42888 | |||
| 578dc9e70b | |||
| 6769db160d | |||
| 56d16aae42 | |||
| d614f4c96d | |||
| 98f0d85c4a | |||
| b3115454ce | |||
| cb3b6ff624 | |||
| a795d6635b | |||
| a2b49322fb | |||
| 0b2006b74f | |||
| a91d0ac156 | |||
| d71995ab5c | |||
| fea2a82ef6 | |||
| 8373cc6c47 | |||
| 872d2046fd | |||
| 44ec142fa9 | |||
| b70f389b64 | |||
| 1c73edd9b0 | |||
| 94d9088034 | |||
| cbd9e560b0 | |||
| abc595b810 | |||
| 7d26d3926c | |||
| 0e55f7a52f | |||
| febe128e72 | |||
| 3afc7b0883 | |||
| 655c9dd526 | |||
| bcea96528a | |||
| 7336e18410 | |||
| 412af0269d | |||
| 5e17afbc0a | |||
| 912236439c | |||
| 0ad4166482 | |||
| 7ce1055656 | |||
| 78a376aa7f | |||
| 43f2b47fc9 | |||
| 413cfed7d7 | |||
| e05b87c8d0 | |||
| 1b4bce4182 | |||
| 387587dedb | |||
| 5d8c8f33c0 | |||
| d032396031 | |||
| 12438b30a0 | |||
| ea1ff9c482 | |||
| 8122156e84 | |||
| 991f4ed993 | |||
| 29244c5c40 | |||
| ca3d855c44 | |||
| 3fcd39f659 | |||
| c2b823f185 | |||
| 7de076481e | |||
| 58cfa3fd49 | |||
| 87e7fa9917 | |||
| b14b0efefe | |||
| 1b271f3335 | |||
| 03e30431a8 | |||
| 5a93449b89 | |||
| 222e05c2d2 | |||
| c0071a0676 | |||
| 97231ca231 | |||
| 67bd28eaaf | |||
| 51b2fd1777 | |||
| ff5eac6da5 | |||
| 4987cb0407 | |||
| 7927f7a440 | |||
| 605284bc36 | |||
| 54ed31ebaf | |||
| 6320bd5849 | |||
| 86cc7f6925 | |||
| adb77e1a92 | |||
| 097f3c9514 | |||
| f0266cbef3 | |||
| 519967cc69 | |||
| a7b9a33efc | |||
| 32b84b8ab6 | |||
| 8ec1c866e1 | |||
| 3a06394fde | |||
| ce72154913 | |||
| ed11f2a9e4 | |||
| 60f2e452a1 | |||
| 76103ee286 | |||
| 73042bfc54 | |||
| ff23397701 | |||
| 96b37f4eb8 | |||
| 135cea76fb | |||
| ff087e126f | |||
| 9501fc2c14 | |||
| 7547291450 | |||
| 0603b4431a | |||
| 5f48f60a93 | |||
| cc9faf3cfa | |||
| 7d93e9963a | |||
| 32cec6c1cb | |||
| c0827e2c54 | |||
| 1a931da046 | |||
| 8eb62f138b | |||
| 6a8921ec6b | |||
| 53132d0235 | |||
| 32bed34935 | |||
| 1873b38a94 | |||
| 38b4a2a8e2 | |||
| b65d9ca955 | |||
| 0b472c23d7 | |||
| bb89ee184f | |||
| eb087c9943 | |||
| eeec6f8fb9 | |||
| 71339225eb | |||
| 590e70d4d1 | |||
| fd16ac4d5e | |||
| f3099afcc5 | |||
| 37f8e6aabd | |||
| e0fe2882ad | |||
| 4413592a70 | |||
| 4c28ee80a6 | |||
| f4c4fe860b | |||
| 4766b475d0 | |||
| ae75d4b565 | |||
| c102387916 | |||
| 86ad215deb | |||
| c3f82534bd | |||
| 2ffbb37783 | |||
| 6821fe0c13 | |||
| a0947232fa | |||
| e3f1a3d27c | |||
| d98e05b91a | |||
| fa85f4fc2e | |||
| 44352b375e | |||
| ebe88ea322 | |||
| 6d77723fe0 | |||
| c5ed51a188 | |||
| 1339c425a8 | |||
| 7c723dfc58 | |||
| 72814a8153 | |||
| 9952f72680 | |||
| b9473bc99c | |||
| cbc3ce5b03 | |||
| d223752c55 | |||
| 74208e9e0c | |||
| 14b7fa1dd6 | |||
| 4bfe8605cb | |||
| e86bf764a8 | |||
| 80411fb905 | |||
| c9241e83dd | |||
| 9166b03c42 | |||
| 31efc882db | |||
| 1db59d1c89 | |||
| afb3715700 | |||
| 6be4279f39 | |||
| 5782871f91 | |||
| 0e9ac9e64b | |||
| 13df99fd1e | |||
| 9f62bd1da6 | |||
| 75c1562df0 | |||
| 0821d5b29d | |||
| b3cffc0516 | |||
| 80a58672d1 | |||
| 18714e25a8 | |||
| b29c30c9d5 | |||
| d8df197489 | |||
| 514e60c1bb | |||
| 32a256bd03 | |||
| b9316a404a | |||
| ea2a3f3e62 | |||
| 5cd8009c53 | |||
| 26aa620efe | |||
| e0cf6e4775 | |||
| df2d43c893 | |||
| 8d6c5ba90e | |||
| 629f528f6d | |||
| 191e3bc7e1 | |||
| ecad4743bd | |||
| ceb8aedf97 | |||
| 0cf4eb379f | |||
| f3fdf58ff7 | |||
| 3073e65851 | |||
| a75529f3c0 | |||
| 75a48aed0b | |||
| a7f23ebe7d | |||
| 0f9a02e6f4 | |||
| 4b4b77ca04 | |||
| a231648607 | |||
| eeb5cd2321 | |||
| 5c705ae9a5 | |||
| 19f69f6ac8 | |||
| ad1340cab4 | |||
| 3a3a59c188 | |||
| 6ed6cc46de | |||
| 6837e80d14 | |||
| 4f3e65e745 | |||
| 36a1b69a19 | |||
| 1f11892de4 | |||
| 1bc8f3ac6e | |||
| e62f10d5f0 | |||
| 822547dfef | |||
| c0214cfcc1 | |||
| cb6d96d65f | |||
| 4cc4868e93 | |||
| 6c90d3a1b6 | |||
| ffab342fc4 | |||
| 1203dc501c | |||
| 3cbf1845a9 | |||
| ea44eade21 | |||
| c75a368bab | |||
| bc8d2add04 | |||
| c53f58e839 | |||
| 50543a7948 | |||
| f7cd22d5ec | |||
| b136c77031 | |||
| 6bfe171058 | |||
| 5e49da1d73 | |||
| cc7ae525ef | |||
| a29853f53b | |||
| 7cea21043e | |||
| cbdea09c92 | |||
| 31393704de | |||
| 3eec90cdc0 | |||
| b9d8eb54b7 | |||
| a2fdb55384 | |||
| 848a19a013 | |||
| 98bc89968a | |||
| 9c0e9e462b | |||
| 57d762d5ea | |||
| 9018ce1125 | |||
| 1b32f5c28b | |||
| 0e35e50f8f | |||
| 88b617646a | |||
| 27fa7eace1 | |||
| ca996e0e85 | |||
| df683205d9 |
+2
-1
@@ -13,7 +13,7 @@ stages:
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v7
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
@@ -40,6 +40,7 @@ fedora-x86_64:
|
||||
script:
|
||||
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
|
||||
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
|
||||
allow_failure: true
|
||||
cache:
|
||||
key: "%CI_JOB_NAME%"
|
||||
<<: *cache-paths
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
FROM fedora:30
|
||||
FROM fedora:31
|
||||
|
||||
RUN dnf -y install \
|
||||
hicolor-icon-theme \
|
||||
adwaita-icon-theme \
|
||||
atk-devel \
|
||||
at-spi2-atk-devel \
|
||||
@@ -14,6 +13,7 @@ RUN dnf -y install \
|
||||
dbus-daemon \
|
||||
dejavu-sans-mono-fonts \
|
||||
desktop-file-utils \
|
||||
diffutils \
|
||||
elfutils-libelf-devel \
|
||||
fribidi-devel \
|
||||
gcc \
|
||||
@@ -32,6 +32,7 @@ RUN dnf -y install \
|
||||
gstreamer1-plugins-bad-free-devel \
|
||||
gstreamer1-plugins-base-devel \
|
||||
gtk-doc \
|
||||
hicolor-icon-theme \
|
||||
iso-codes \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
|
||||
@@ -149,11 +149,11 @@ ul.images li {
|
||||
<article>
|
||||
<section>
|
||||
<div class="summary">
|
||||
<h3>Summary</h3>
|
||||
<h3><a name="summary">Summary</a></h3>
|
||||
<ul>
|
||||
<li><strong>Total units:</strong> {{ report.total_units }}</li>
|
||||
<li><strong>Passed:</strong> {{ report.total_successes }}</li>
|
||||
<li><strong>Failed:</strong> {{ report.total_failures }}</li>
|
||||
<li><strong>Passed:</strong> <a href="#passed">{{ report.total_successes }}</a></li>
|
||||
<li><strong>Failed:</strong> <a href="#failures">{{ report.total_failures }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
@@ -161,7 +161,7 @@ ul.images li {
|
||||
{% for suite_result in report.results_list %}
|
||||
<section>
|
||||
<div class="result">
|
||||
<h3>Suite: {{ suite_result.suite_name }}</h3>
|
||||
<h3><a name="results">Suite: {{ suite_result.suite_name }}</a></h3>
|
||||
<ul>
|
||||
<li><strong>Units:</strong> {{ suite_result.n_units }}</li>
|
||||
<li><strong>Passed:</strong> {{ suite_result.n_successes }}</li>
|
||||
@@ -169,7 +169,7 @@ ul.images li {
|
||||
</ul>
|
||||
|
||||
<div class="successes">
|
||||
<h4>Passed</h4>
|
||||
<h4><a name="passed">Passed</a></h4>
|
||||
<ul class="passed">
|
||||
{% for success in suite_result.successes if success.result == 'OK' %}
|
||||
<li>{{ success.name }} - result: <span class="result pass">{{ success.result }}</li>
|
||||
@@ -178,7 +178,7 @@ ul.images li {
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Skipped</h4>
|
||||
<h4><a name="skipped">Skipped</a></h4>
|
||||
<ul>
|
||||
{% for success in suite_result.successes if success.result == 'SKIP' %}
|
||||
<li>{{ success.name }} - result: <span class="result skip">{{ success.result }}</li>
|
||||
@@ -187,10 +187,10 @@ ul.images li {
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Expected failures</h4>
|
||||
<h4><a name="expected-fail">Expected failures</a></h4>
|
||||
<ul>
|
||||
{% for success in suite_result.successes if success.result == 'EXPECTEDFAIL' %}
|
||||
<li>{{ success.name }} - result: <span class="result xfail">{{ success.result }}</span><br/>
|
||||
<li><a name="{{ success.name }}">{{ success.name }}</a> - result: <span class="result xfail">{{ success.result }}</span><br/>
|
||||
{% if success.stdout %}
|
||||
Output: <pre>{{ success.stdout }}</pre>
|
||||
{% endif %}
|
||||
@@ -209,10 +209,10 @@ ul.images li {
|
||||
</div>
|
||||
|
||||
<div class="failures">
|
||||
<h4>Failed</h4>
|
||||
<h4><a name="failed">Failed</a></h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'FAIL' %}
|
||||
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
{% if failure.stdout %}
|
||||
Output: <pre>{{ failure.stdout }}</pre>
|
||||
{% endif %}
|
||||
@@ -229,10 +229,10 @@ ul.images li {
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Timed out</h4>
|
||||
<h4><a name="timed-out">Timed out</a></h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'TIMEOUT' %}
|
||||
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
{% if failure.stdout %}
|
||||
Output: <pre>{{ failure.stdout }}</pre>
|
||||
{% endif %}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v6"
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v7"
|
||||
|
||||
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||
--file "Dockerfile" .
|
||||
|
||||
@@ -110,7 +110,7 @@ get_image_paintable (GtkImage *image)
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, 48, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
|
||||
if (icon_info == NULL)
|
||||
return NULL;
|
||||
return GDK_PAINTABLE (gtk_icon_info_load_texture (icon_info));
|
||||
return gtk_icon_info_load_icon (icon_info, NULL);
|
||||
default:
|
||||
g_warning ("Image storage type %d not handled",
|
||||
gtk_image_get_storage_type (image));
|
||||
|
||||
@@ -104,6 +104,9 @@
|
||||
<file>gtkfishbowl.c</file>
|
||||
<file>gtkfishbowl.h</file>
|
||||
</gresource>
|
||||
<gresource prefix="/iconscroll">
|
||||
<file>iconscroll.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/iconview">
|
||||
<file>gnome-fs-directory.png</file>
|
||||
<file>gnome-fs-regular.png</file>
|
||||
@@ -164,8 +167,8 @@
|
||||
<file>drawingarea.c</file>
|
||||
<file>dnd.c</file>
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_buffer.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
<file>entry_undo.c</file>
|
||||
<file>expander.c</file>
|
||||
<file>filtermodel.c</file>
|
||||
<file>fishbowl.c</file>
|
||||
@@ -179,6 +182,7 @@
|
||||
<file>glarea.c</file>
|
||||
<file>headerbar.c</file>
|
||||
<file>hypertext.c</file>
|
||||
<file>iconscroll.c</file>
|
||||
<file>iconview.c</file>
|
||||
<file>iconview_edit.c</file>
|
||||
<file>images.c</file>
|
||||
@@ -216,6 +220,7 @@
|
||||
<file>spinner.c</file>
|
||||
<file>tabs.c</file>
|
||||
<file>tagged_entry.c</file>
|
||||
<file>textundo.c</file>
|
||||
<file>textview.c</file>
|
||||
<file>textscroll.c</file>
|
||||
<file>theming_style_classes.c</file>
|
||||
|
||||
@@ -129,13 +129,13 @@ demo_tagged_entry_size_allocate (GtkWidget *widget,
|
||||
baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
demo_tagged_entry_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
gtk_widget_grab_focus (priv->entry);
|
||||
return gtk_widget_grab_focus (priv->entry);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
/* Entry/Entry Buffer
|
||||
/* Entry/Entry Undo
|
||||
*
|
||||
* GtkEntryBuffer provides the text content in a GtkEntry.
|
||||
* Applications can provide their own buffer implementation,
|
||||
* e.g. to provide secure handling for passwords in memory.
|
||||
* GtkEntry can provide basic Undo/Redo support using standard keyboard
|
||||
* accelerators such as Primary+z to undo and Primary+Shift+z to redo.
|
||||
* Additionally, Primary+y can be used to redo.
|
||||
*
|
||||
* Use gtk_entry_set_enable_undo() to enable undo/redo support.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
GtkWidget *
|
||||
do_entry_buffer (GtkWidget *do_widget)
|
||||
do_entry_undo (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry;
|
||||
GtkEntryBuffer *buffer;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Buffer");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Undo");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
@@ -33,22 +34,13 @@ do_entry_buffer (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"Entries share a buffer. Typing in one is reflected in the other.");
|
||||
"Use Primary+z or Primary+Shift+z to undo or redo changes");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
/* Create a buffer */
|
||||
buffer = gtk_entry_buffer_new (NULL, 0);
|
||||
|
||||
/* Create our first entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
/* Create our entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
@@ -52,7 +52,7 @@ do_expander (GtkWidget *do_widget)
|
||||
area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window));
|
||||
|
||||
label = gtk_widget_get_last_child (area);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), FALSE);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), FALSE);
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
|
||||
expander = gtk_expander_new ("Details:");
|
||||
|
||||
@@ -124,7 +124,7 @@ create_label (void)
|
||||
{
|
||||
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
|
||||
gtk_label_set_wrap (GTK_LABEL (w), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
|
||||
|
||||
return w;
|
||||
|
||||
+139
-626
@@ -15,10 +15,6 @@
|
||||
#include <pango/pangofc-font.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
#include <hb-ft.h>
|
||||
#include <freetype/ftmm.h>
|
||||
#include <freetype/ftsnames.h>
|
||||
#include <freetype/ttnameid.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "open-type-layout.h"
|
||||
@@ -484,7 +480,6 @@ update_script_combo (void)
|
||||
GtkListStore *store;
|
||||
hb_font_t *hb_font;
|
||||
gint i, j, k;
|
||||
FT_Face ft_face;
|
||||
PangoFont *pango_font;
|
||||
GHashTable *tags;
|
||||
GHashTableIter iter;
|
||||
@@ -505,8 +500,7 @@ update_script_combo (void)
|
||||
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
|
||||
hb_font = hb_ft_font_create (ft_face, NULL);
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
|
||||
tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL);
|
||||
|
||||
@@ -545,11 +539,8 @@ update_script_combo (void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hb_face_destroy (hb_face);
|
||||
}
|
||||
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
g_object_unref (pango_font);
|
||||
|
||||
g_hash_table_iter_init (&iter, tags);
|
||||
@@ -607,7 +598,6 @@ update_features (void)
|
||||
GtkTreeIter iter;
|
||||
guint script_index, lang_index;
|
||||
PangoFont *pango_font;
|
||||
FT_Face ft_face;
|
||||
hb_font_t *hb_font;
|
||||
GList *l;
|
||||
|
||||
@@ -632,8 +622,7 @@ update_features (void)
|
||||
-1);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
|
||||
hb_font = hb_ft_font_create (ft_face, NULL);
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
|
||||
if (hb_font)
|
||||
{
|
||||
@@ -715,11 +704,8 @@ update_features (void)
|
||||
|
||||
g_free (feat);
|
||||
}
|
||||
|
||||
hb_face_destroy (hb_face);
|
||||
}
|
||||
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
g_object_unref (pango_font);
|
||||
}
|
||||
|
||||
@@ -800,24 +786,29 @@ axes_equal (gconstpointer v1, gconstpointer v2)
|
||||
}
|
||||
|
||||
static void
|
||||
add_axis (FT_Var_Axis *ax, FT_Fixed value, int i)
|
||||
add_axis (hb_face_t *hb_face,
|
||||
hb_ot_var_axis_info_t *ax,
|
||||
float value,
|
||||
int i)
|
||||
{
|
||||
GtkWidget *axis_label;
|
||||
GtkWidget *axis_entry;
|
||||
GtkWidget *axis_scale;
|
||||
GtkAdjustment *adjustment;
|
||||
Axis *axis;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
axis_label = gtk_label_new (ax->name);
|
||||
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
|
||||
axis_label = gtk_label_new (name);
|
||||
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (variations_grid), axis_label, 0, i, 1, 1);
|
||||
adjustment = gtk_adjustment_new ((double)FixedToFloat(value),
|
||||
(double)FixedToFloat(ax->minimum),
|
||||
(double)FixedToFloat(ax->maximum),
|
||||
adjustment = gtk_adjustment_new (value, ax->min_value, ax->max_value,
|
||||
1.0, 10.0, 0.0);
|
||||
axis_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
|
||||
gtk_scale_add_mark (GTK_SCALE (axis_scale), (double)FixedToFloat(ax->def), GTK_POS_TOP, NULL);
|
||||
gtk_scale_add_mark (GTK_SCALE (axis_scale), ax->default_value, GTK_POS_TOP, NULL);
|
||||
gtk_widget_set_valign (axis_scale, GTK_ALIGN_BASELINE);
|
||||
gtk_widget_set_hexpand (axis_scale, TRUE);
|
||||
gtk_widget_set_size_request (axis_scale, 100, -1);
|
||||
@@ -842,9 +833,7 @@ add_axis (FT_Var_Axis *ax, FT_Fixed value, int i)
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int n_axes;
|
||||
guint32 *axes;
|
||||
float *coords;
|
||||
unsigned int index;
|
||||
} Instance;
|
||||
|
||||
static guint
|
||||
@@ -870,559 +859,32 @@ free_instance (gpointer data)
|
||||
Instance *instance = data;
|
||||
|
||||
g_free (instance->name);
|
||||
g_free (instance->axes);
|
||||
g_free (instance->coords);
|
||||
g_free (instance);
|
||||
}
|
||||
|
||||
static GHashTable *instances;
|
||||
|
||||
typedef struct {
|
||||
const FT_UShort platform_id;
|
||||
const FT_UShort encoding_id;
|
||||
const char fromcode[12];
|
||||
} FtEncoding;
|
||||
|
||||
#define TT_ENCODING_DONT_CARE 0xffff
|
||||
|
||||
static const FtEncoding ftEncoding[] = {
|
||||
{ TT_PLATFORM_APPLE_UNICODE, TT_ENCODING_DONT_CARE, "UTF-16BE" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, "MACINTOSH" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_JAPANESE, "SJIS" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, "UTF-16BE" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, "UTF-16BE" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, "SJIS-WIN" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, "GB2312" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, "BIG-5" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, "Wansung" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, "Johab" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, "UTF-16BE" },
|
||||
{ TT_PLATFORM_ISO, TT_ISO_ID_7BIT_ASCII, "ASCII" },
|
||||
{ TT_PLATFORM_ISO, TT_ISO_ID_10646, "UTF-16BE" },
|
||||
{ TT_PLATFORM_ISO, TT_ISO_ID_8859_1, "ISO-8859-1" },
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const FT_UShort platform_id;
|
||||
const FT_UShort language_id;
|
||||
const char lang[8];
|
||||
} FtLanguage;
|
||||
|
||||
#define TT_LANGUAGE_DONT_CARE 0xffff
|
||||
|
||||
static const FtLanguage ftLanguage[] = {
|
||||
{ TT_PLATFORM_APPLE_UNICODE, TT_LANGUAGE_DONT_CARE, "" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ENGLISH, "en" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FRENCH, "fr" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GERMAN, "de" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ITALIAN, "it" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_DUTCH, "nl" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SWEDISH, "sv" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SPANISH, "es" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_DANISH, "da" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_PORTUGUESE, "pt" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_NORWEGIAN, "no" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_HEBREW, "he" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_JAPANESE, "ja" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ARABIC, "ar" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FINNISH, "fi" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GREEK, "el" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ICELANDIC, "is" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALTESE, "mt" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TURKISH, "tr" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CROATIAN, "hr" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CHINESE_TRADITIONAL, "zh-tw" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_URDU, "ur" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_HINDI, "hi" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_THAI, "th" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KOREAN, "ko" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LITHUANIAN, "lt" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_POLISH, "pl" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_HUNGARIAN, "hu" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ESTONIAN, "et" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LETTISH, "lv" },
|
||||
/* { TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SAAMISK, ??? */
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FAEROESE, "fo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FARSI, "fa" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_RUSSIAN, "ru" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CHINESE_SIMPLIFIED, "zh-cn" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FLEMISH, "nl" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_IRISH, "ga" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ALBANIAN, "sq" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ROMANIAN, "ro" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CZECH, "cs" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SLOVAK, "sk" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SLOVENIAN, "sl" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_YIDDISH, "yi" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SERBIAN, "sr" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MACEDONIAN, "mk" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BULGARIAN, "bg" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_UKRAINIAN, "uk" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BYELORUSSIAN, "be" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_UZBEK, "uz" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KAZAKH, "kk" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI, "az" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT, "az" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT, "ar" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ARMENIAN, "hy" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GEORGIAN, "ka" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MOLDAVIAN, "mo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KIRGHIZ, "ky" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TAJIKI, "tg" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TURKMEN, "tk" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MONGOLIAN, "mo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT,"mo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT, "mo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_PASHTO, "ps" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KURDISH, "ku" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KASHMIRI, "ks" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SINDHI, "sd" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TIBETAN, "bo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_NEPALI, "ne" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SANSKRIT, "sa" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MARATHI, "mr" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BENGALI, "bn" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ASSAMESE, "as" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GUJARATI, "gu" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_PUNJABI, "pa" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ORIYA, "or" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAYALAM, "ml" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KANNADA, "kn" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TAMIL, "ta" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TELUGU, "te" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SINHALESE, "si" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BURMESE, "my" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_KHMER, "km" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LAO, "lo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_VIETNAMESE, "vi" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_INDONESIAN, "id" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TAGALOG, "tl" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAY_ROMAN_SCRIPT, "ms" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAY_ARABIC_SCRIPT, "ms" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AMHARIC, "am" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TIGRINYA, "ti" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GALLA, "om" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SOMALI, "so" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SWAHILI, "sw" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_RUANDA, "rw" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_RUNDI, "rn" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CHEWA, "ny" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MALAGASY, "mg" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ESPERANTO, "eo" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_WELSH, "cy" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BASQUE, "eu" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_CATALAN, "ca" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_LATIN, "la" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_QUECHUA, "qu" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GUARANI, "gn" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AYMARA, "ay" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TATAR, "tt" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_UIGHUR, "ug" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_DZONGKHA, "dz" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_JAVANESE, "jw" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SUNDANESE, "su" },
|
||||
|
||||
#if 0 /* these seem to be errors that have been dropped */
|
||||
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SCOTTISH_GAELIC },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_IRISH_GAELIC },
|
||||
|
||||
#endif
|
||||
|
||||
/* The following codes are new as of 2000-03-10 */
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GALICIAN, "gl" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AFRIKAANS, "af" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_BRETON, "br" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_INUKTITUT, "iu" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_SCOTTISH_GAELIC, "gd" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_MANX_GAELIC, "gv" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_IRISH_GAELIC, "ga" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_TONGAN, "to" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GREEK_POLYTONIC, "el" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GREELANDIC, "ik" },
|
||||
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT,"az" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_SAUDI_ARABIA, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_IRAQ, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_EGYPT, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_LIBYA, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_ALGERIA, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_MOROCCO, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_TUNISIA, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_OMAN, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_YEMEN, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_SYRIA, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_JORDAN, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_LEBANON, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_KUWAIT, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_UAE, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_BAHRAIN, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_QATAR, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BULGARIAN_BULGARIA, "bg" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CATALAN_SPAIN, "ca" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_TAIWAN, "zh-tw" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_PRC, "zh-cn" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_HONG_KONG, "zh-hk" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_SINGAPORE, "zh-sg" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_MACAU, "zh-mo" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CZECH_CZECH_REPUBLIC, "cs" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DANISH_DENMARK, "da" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_GERMANY, "de" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_SWITZERLAND, "de" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_AUSTRIA, "de" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_LUXEMBOURG, "de" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GERMAN_LIECHTENSTEI, "de" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GREEK_GREECE, "el" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_UNITED_STATES, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_UNITED_KINGDOM, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_AUSTRALIA, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_CANADA, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_NEW_ZEALAND, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_IRELAND, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_SOUTH_AFRICA, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_JAMAICA, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_CARIBBEAN, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_BELIZE, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_TRINIDAD, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_ZIMBABWE, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_PHILIPPINES, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT,"es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_MEXICO, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT,"es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_GUATEMALA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_COSTA_RICA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PANAMA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC,"es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_VENEZUELA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_COLOMBIA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PERU, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_ARGENTINA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_ECUADOR, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_CHILE, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_URUGUAY, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PARAGUAY, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_BOLIVIA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_EL_SALVADOR, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_HONDURAS, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_NICARAGUA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_PUERTO_RICO, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FINNISH_FINLAND, "fi" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_FRANCE, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_BELGIUM, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_CANADA, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_SWITZERLAND, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_LUXEMBOURG, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_MONACO, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HEBREW_ISRAEL, "he" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HUNGARIAN_HUNGARY, "hu" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ICELANDIC_ICELAND, "is" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ITALIAN_ITALY, "it" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ITALIAN_SWITZERLAND, "it" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_JAPANESE_JAPAN, "ja" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA,"ko" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KOREAN_JOHAB_KOREA, "ko" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DUTCH_NETHERLANDS, "nl" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DUTCH_BELGIUM, "nl" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL, "no" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK, "nn" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_POLISH_POLAND, "pl" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PORTUGUESE_BRAZIL, "pt" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PORTUGUESE_PORTUGAL, "pt" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND,"rm" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ROMANIAN_ROMANIA, "ro" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MOLDAVIAN_MOLDAVIA, "mo" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_RUSSIAN_RUSSIA, "ru" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_RUSSIAN_MOLDAVIA, "ru" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CROATIAN_CROATIA, "hr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SERBIAN_SERBIA_LATIN, "sr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC, "sr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SLOVAK_SLOVAKIA, "sk" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ALBANIAN_ALBANIA, "sq" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SWEDISH_SWEDEN, "sv" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SWEDISH_FINLAND, "sv" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_THAI_THAILAND, "th" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TURKISH_TURKEY, "tr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_URDU_PAKISTAN, "ur" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_INDONESIAN_INDONESIA, "id" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_UKRAINIAN_UKRAINE, "uk" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BELARUSIAN_BELARUS, "be" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SLOVENE_SLOVENIA, "sl" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ESTONIAN_ESTONIA, "et" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LATVIAN_LATVIA, "lv" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LITHUANIAN_LITHUANIA, "lt" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA,"lt" },
|
||||
|
||||
#ifdef TT_MS_LANGID_MAORI_NEW_ZELAND
|
||||
/* this seems to be an error that have been dropped */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MAORI_NEW_ZEALAND, "mi" },
|
||||
#endif
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FARSI_IRAN, "fa" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_VIETNAMESE_VIET_NAM, "vi" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARMENIAN_ARMENIA, "hy" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN, "az" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC, "az" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BASQUE_SPAIN, "eu" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SORBIAN_GERMANY, "wen" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MACEDONIAN_MACEDONIA, "mk" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SUTU_SOUTH_AFRICA, "st" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TSONGA_SOUTH_AFRICA, "ts" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TSWANA_SOUTH_AFRICA, "tn" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_VENDA_SOUTH_AFRICA, "ven" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_XHOSA_SOUTH_AFRICA, "xh" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ZULU_SOUTH_AFRICA, "zu" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA, "af" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GEORGIAN_GEORGIA, "ka" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS, "fo" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HINDI_INDIA, "hi" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALTESE_MALTA, "mt" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SAAMI_LAPONIA, "se" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM,"gd" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_IRISH_GAELIC_IRELAND, "ga" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALAY_MALAYSIA, "ms" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM, "ms" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KAZAK_KAZAKSTAN, "kk" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SWAHILI_KENYA, "sw" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN, "uz" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC, "uz" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TATAR_TATARSTAN, "tt" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BENGALI_INDIA, "bn" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PUNJABI_INDIA, "pa" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GUJARATI_INDIA, "gu" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ORIYA_INDIA, "or" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAMIL_INDIA, "ta" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TELUGU_INDIA, "te" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KANNADA_INDIA, "kn" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MALAYALAM_INDIA, "ml" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ASSAMESE_INDIA, "as" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MARATHI_INDIA, "mr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SANSKRIT_INDIA, "sa" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KONKANI_INDIA, "kok" },
|
||||
|
||||
/* new as of 2001-01-01 */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ARABIC_GENERAL, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHINESE_GENERAL, "zh" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_GENERAL, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_WEST_INDIES, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_REUNION, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_CONGO, "fr" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_SENEGAL, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_CAMEROON, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_COTE_D_IVOIRE, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_MALI, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA,"bs" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_URDU_INDIA, "ur" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAJIK_TAJIKISTAN, "tg" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_YIDDISH_GERMANY, "yi" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN, "ky" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TURKMEN_TURKMENISTAN, "tk" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MONGOLIAN_MONGOLIA, "mn" },
|
||||
|
||||
/* the following seems to be inconsistent;
|
||||
here is the current "official" way: */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIBETAN_BHUTAN, "bo" },
|
||||
/* and here is what is used by Passport SDK */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIBETAN_CHINA, "bo" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DZONGHKA_BHUTAN, "dz" },
|
||||
/* end of inconsistency */
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_WELSH_WALES, "cy" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KHMER_CAMBODIA, "km" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LAO_LAOS, "lo" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BURMESE_MYANMAR, "my" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GALICIAN_SPAIN, "gl" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MANIPURI_INDIA, "mni" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SINDHI_INDIA, "sd" },
|
||||
/* the following one is only encountered in Microsoft RTF specification */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KASHMIRI_PAKISTAN, "ks" },
|
||||
/* the following one is not in the Passport list, looks like an omission */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KASHMIRI_INDIA, "ks" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NEPALI_NEPAL, "ne" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_NEPALI_INDIA, "ne" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRISIAN_NETHERLANDS, "fy" },
|
||||
|
||||
/* new as of 2001-03-01 (from Office Xp) */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_HONG_KONG, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_INDIA, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_MALAYSIA, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_ENGLISH_SINGAPORE, "en" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SYRIAC_SYRIA, "syr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SINHALESE_SRI_LANKA, "si" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_CHEROKEE_UNITED_STATES, "chr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_INUKTITUT_CANADA, "iu" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_AMHARIC_ETHIOPIA, "am" },
|
||||
#if 0
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAMAZIGHT_MOROCCO },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN },
|
||||
#endif
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PASHTO_AFGHANISTAN, "ps" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FILIPINO_PHILIPPINES, "phi" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_DHIVEHI_MALDIVES, "div" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_OROMO_ETHIOPIA, "om" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIGRIGNA_ETHIOPIA, "ti" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_TIGRIGNA_ERYTHREA, "ti" },
|
||||
|
||||
/* New additions from Windows Xp/Passport SDK 2001-11-10. */
|
||||
|
||||
/* don't ask what this one means... It is commented out currently. */
|
||||
#if 0
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GREEK_GREECE2 },
|
||||
#endif
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_UNITED_STATES, "es" },
|
||||
/* The following two IDs blatantly violate MS specs by using a */
|
||||
/* sublanguage >,. */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SPANISH_LATIN_AMERICA, "es" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_NORTH_AFRICA, "fr" },
|
||||
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_MOROCCO, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FRENCH_HAITI, "fr" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_BENGALI_BANGLADESH, "bn" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN, "ar" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN,"mn" },
|
||||
#if 0
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_EDO_NIGERIA },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_FULFULDE_NIGERIA },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_IBIBIO_NIGERIA },
|
||||
#endif
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HAUSA_NIGERIA, "ha" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_YORUBA_NIGERIA, "yo" },
|
||||
/* language codes from, to, are (still) unknown. */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_IGBO_NIGERIA, "ibo" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_KANURI_NIGERIA, "kau" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_GUARANI_PARAGUAY, "gn" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_HAWAIIAN_UNITED_STATES, "haw" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_LATIN, "la" },
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_SOMALI_SOMALIA, "so" },
|
||||
#if 0
|
||||
/* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
|
||||
/* not written (but OTOH the peculiar writing system is worth */
|
||||
/* studying). */
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_YI_CHINA },
|
||||
#endif
|
||||
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES,"pap" },
|
||||
};
|
||||
|
||||
static const char *
|
||||
FcSfntNameLanguage (FT_SfntName *sname)
|
||||
{
|
||||
int i;
|
||||
FT_UShort platform_id = sname->platform_id;
|
||||
FT_UShort language_id = sname->language_id;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (ftLanguage); i++)
|
||||
if (ftLanguage[i].platform_id == platform_id &&
|
||||
(ftLanguage[i].language_id == TT_LANGUAGE_DONT_CARE ||
|
||||
ftLanguage[i].language_id == language_id))
|
||||
{
|
||||
if (ftLanguage[i].lang[0] == '\0')
|
||||
return NULL;
|
||||
else
|
||||
return ftLanguage[i].lang;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
FcSfntNameTranscode (FT_SfntName *name)
|
||||
{
|
||||
int i;
|
||||
const char *fromcode;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (ftEncoding); i++)
|
||||
if (ftEncoding[i].platform_id == name->platform_id &&
|
||||
(ftEncoding[i].encoding_id == TT_ENCODING_DONT_CARE ||
|
||||
ftEncoding[i].encoding_id == name->encoding_id))
|
||||
break;
|
||||
if (i == G_N_ELEMENTS (ftEncoding))
|
||||
return NULL;
|
||||
fromcode = ftEncoding[i].fromcode;
|
||||
|
||||
return g_convert ((const char *)name->string, name->string_len, "UTF-8", fromcode, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_sfnt_name (FT_Face ft_face,
|
||||
guint nameid)
|
||||
{
|
||||
guint count;
|
||||
guint i, j;
|
||||
const char * const *langs = g_get_language_names ();
|
||||
char *res = NULL;
|
||||
guint pos = G_MAXUINT;
|
||||
|
||||
count = FT_Get_Sfnt_Name_Count (ft_face);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
FT_SfntName name;
|
||||
const char *lang;
|
||||
|
||||
if (FT_Get_Sfnt_Name (ft_face, i, &name) != 0)
|
||||
continue;
|
||||
|
||||
if (name.name_id != nameid)
|
||||
continue;
|
||||
|
||||
lang = FcSfntNameLanguage (&name);
|
||||
for (j = 0; j < pos && langs[j]; j++)
|
||||
{
|
||||
if (strcmp (lang, langs[j]) == 0)
|
||||
{
|
||||
pos = j;
|
||||
g_free (res);
|
||||
res = FcSfntNameTranscode (&name);
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_valid_subfamily_id (guint id)
|
||||
{
|
||||
return id == 2 || id == 17 || (255 < id && id < 32768);
|
||||
}
|
||||
|
||||
static void
|
||||
add_instance (FT_Face ft_face,
|
||||
FT_MM_Var *ft_mm_var,
|
||||
FT_Var_Named_Style *ns,
|
||||
GtkWidget *combo,
|
||||
int pos)
|
||||
add_instance (hb_face_t *face,
|
||||
unsigned int index,
|
||||
GtkWidget *combo,
|
||||
int pos)
|
||||
{
|
||||
Instance *instance;
|
||||
int i;
|
||||
hb_ot_name_id_t name_id;
|
||||
char name[20];
|
||||
unsigned int name_len = 20;
|
||||
|
||||
instance = g_new0 (Instance, 1);
|
||||
|
||||
if (is_valid_subfamily_id (ns->strid))
|
||||
instance->name = get_sfnt_name (ft_face, ns->strid);
|
||||
if (!instance->name)
|
||||
instance->name = g_strdup_printf ("Instance %d", pos);
|
||||
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, index);
|
||||
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
|
||||
|
||||
instance->name = g_strdup_printf (name);
|
||||
instance->index = index;
|
||||
|
||||
g_hash_table_add (instances, instance);
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
|
||||
|
||||
instance->n_axes = ft_mm_var->num_axis;
|
||||
instance->axes = g_new (guint32, ft_mm_var->num_axis);
|
||||
instance->coords = g_new (float, ft_mm_var->num_axis);
|
||||
|
||||
for (i = 0; i < ft_mm_var->num_axis; i++)
|
||||
{
|
||||
instance->axes[i] = ft_mm_var->axis[i].tag;
|
||||
instance->coords[i] = FixedToFloat(ns->coords[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1439,6 +901,13 @@ instance_changed (GtkComboBox *combo)
|
||||
Instance *instance;
|
||||
Instance ikey;
|
||||
int i;
|
||||
unsigned int coords_length;
|
||||
float *coords = NULL;
|
||||
hb_ot_var_axis_info_t *ai = NULL;
|
||||
unsigned int n_axes;
|
||||
PangoFont *pango_font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
|
||||
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
|
||||
if (text[0] == '\0')
|
||||
@@ -1452,17 +921,29 @@ instance_changed (GtkComboBox *combo)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < instance->n_axes; i++)
|
||||
pango_font = get_pango_font ();
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
ai = g_new (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
|
||||
|
||||
coords = g_new (float, n_axes);
|
||||
hb_ot_var_named_instance_get_design_coords (hb_face,
|
||||
instance->index,
|
||||
&coords_length,
|
||||
coords);
|
||||
|
||||
for (i = 0; i < n_axes; i++)
|
||||
{
|
||||
Axis *axis;
|
||||
Axis akey;
|
||||
guint32 tag;
|
||||
gdouble value;
|
||||
|
||||
tag = instance->axes[i];
|
||||
value = instance->coords[i];
|
||||
value = coords[ai[i].axis_index];
|
||||
|
||||
akey.tag = tag;
|
||||
akey.tag = ai[i].tag;
|
||||
axis = g_hash_table_lookup (axes, &akey);
|
||||
if (axis)
|
||||
{
|
||||
@@ -1474,17 +955,31 @@ instance_changed (GtkComboBox *combo)
|
||||
|
||||
out:
|
||||
g_free (text);
|
||||
g_clear_object (&pango_font);
|
||||
g_free (ai);
|
||||
g_free (coords);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
matches_instance (FT_Var_Named_Style *instance,
|
||||
FT_Fixed *coords,
|
||||
FT_UInt num_coords)
|
||||
matches_instance (hb_face_t *hb_face,
|
||||
unsigned int index,
|
||||
unsigned int n_axes,
|
||||
float *coords)
|
||||
{
|
||||
FT_UInt i;
|
||||
float *instance_coords;
|
||||
unsigned int coords_length;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_coords; i++)
|
||||
if (coords[i] != instance->coords[i])
|
||||
instance_coords = g_new (float, n_axes);
|
||||
coords_length = n_axes;
|
||||
|
||||
hb_ot_var_named_instance_get_design_coords (hb_face,
|
||||
index,
|
||||
&coords_length,
|
||||
instance_coords);
|
||||
|
||||
for (i = 0; i < n_axes; i++)
|
||||
if (instance_coords[i] != coords[i])
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@@ -1515,14 +1010,31 @@ add_font_plane (int i)
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: This doesn't work if the font has an avar table */
|
||||
static float
|
||||
denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
|
||||
{
|
||||
float r = coord / 16384.0;
|
||||
|
||||
if (coord < 0)
|
||||
return axis->default_value + r * (axis->default_value - axis->min_value);
|
||||
else
|
||||
return axis->default_value + r * (axis->max_value - axis->default_value);
|
||||
}
|
||||
|
||||
static void
|
||||
update_font_variations (void)
|
||||
{
|
||||
GtkWidget *child, *next;
|
||||
PangoFont *pango_font;
|
||||
FT_Face ft_face;
|
||||
FT_MM_Var *ft_mm_var;
|
||||
FT_Error ret;
|
||||
PangoFont *pango_font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
unsigned int n_axes;
|
||||
hb_ot_var_axis_info_t *ai = NULL;
|
||||
float *design_coords = NULL;
|
||||
const int *coords;
|
||||
unsigned int length;
|
||||
int i;
|
||||
|
||||
child = gtk_widget_get_first_child (variations_grid);
|
||||
while (child != NULL)
|
||||
@@ -1538,62 +1050,63 @@ update_font_variations (void)
|
||||
g_hash_table_remove_all (instances);
|
||||
|
||||
pango_font = get_pango_font ();
|
||||
ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
|
||||
if (ret == 0)
|
||||
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
|
||||
if (n_axes == 0)
|
||||
goto done;
|
||||
|
||||
ai = g_new0 (hb_ot_var_axis_info_t, n_axes);
|
||||
design_coords = g_new (float, n_axes);
|
||||
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
|
||||
coords = hb_font_get_var_coords_normalized (hb_font, &length);
|
||||
for (i = 0; i < length; i++)
|
||||
design_coords[i] = denorm_coord (&ai[i], coords[i]);
|
||||
|
||||
if (hb_ot_var_get_named_instance_count (hb_face) > 0)
|
||||
{
|
||||
unsigned int i;
|
||||
FT_Fixed *coords;
|
||||
GtkWidget *label;
|
||||
GtkWidget *combo;
|
||||
|
||||
coords = g_new (FT_Fixed, ft_mm_var->num_axis);
|
||||
ret = FT_Get_Var_Design_Coordinates (ft_face, ft_mm_var->num_axis, coords);
|
||||
label = gtk_label_new ("Instance");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (variations_grid), label, 0, -1, 2, 1);
|
||||
|
||||
if (ft_mm_var->num_namedstyles > 0)
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
add_instance (hb_face, i, combo, i);
|
||||
|
||||
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
|
||||
{
|
||||
GtkWidget *label;
|
||||
GtkWidget *combo;
|
||||
|
||||
label = gtk_label_new ("Instance");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
|
||||
gtk_grid_attach (GTK_GRID (variations_grid), label, 0, -1, 2, 1);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
|
||||
gtk_grid_attach (GTK_GRID (variations_grid), combo, 1, -1, 2, 1);
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
|
||||
|
||||
for (i = 0; i < ft_mm_var->num_namedstyles; i++)
|
||||
add_instance (ft_face, ft_mm_var, &ft_mm_var->namedstyle[i], combo, i);
|
||||
for (i = 0; i < ft_mm_var->num_namedstyles; i++)
|
||||
{
|
||||
if (matches_instance (&ft_mm_var->namedstyle[i], coords, ft_mm_var->num_axis))
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
instance_combo = combo;
|
||||
if (matches_instance (hb_face, i, n_axes, design_coords))
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
for (i = 0; i < ft_mm_var->num_axis; i++)
|
||||
add_axis (&ft_mm_var->axis[i], coords[i], i);
|
||||
gtk_grid_attach (GTK_GRID (variations_grid), combo, 1, -1, 2, 1);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
|
||||
instance_combo = combo;
|
||||
}
|
||||
|
||||
add_font_plane (ft_mm_var->num_axis);
|
||||
}
|
||||
g_free (coords);
|
||||
free (ft_mm_var);
|
||||
}
|
||||
for (i = 0; i < n_axes; i++)
|
||||
add_axis (hb_face, &ai[i], design_coords[i], i);
|
||||
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
g_object_unref (pango_font);
|
||||
add_font_plane (n_axes);
|
||||
|
||||
done:
|
||||
g_clear_object (&pango_font);
|
||||
g_free (ai);
|
||||
g_free (design_coords);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -829,7 +829,6 @@ draw_spinbutton (GtkWidget *widget,
|
||||
GtkStyleContext *down_context;
|
||||
GtkIconTheme *icon_theme;
|
||||
GtkIconInfo *icon_info;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkTexture *texture;
|
||||
gint icon_width, icon_height, icon_size;
|
||||
gint button_width;
|
||||
@@ -857,26 +856,22 @@ draw_spinbutton (GtkWidget *widget,
|
||||
"min-width", &icon_width, "min-height", &icon_height, NULL);
|
||||
icon_size = MIN (icon_width, icon_height);
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-add-symbolic", icon_size, 0);
|
||||
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, up_context, NULL, NULL);
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (icon_info, up_context, NULL, NULL));
|
||||
g_object_unref (icon_info);
|
||||
draw_style_common (up_context, cr, x + width - button_width, y, button_width, *height,
|
||||
&contents_x, &contents_y, &contents_width, &contents_height);
|
||||
gtk_render_icon (up_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (texture);
|
||||
|
||||
gtk_style_context_get (down_context,
|
||||
"min-width", &icon_width, "min-height", &icon_height, NULL);
|
||||
icon_size = MIN (icon_width, icon_height);
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-remove-symbolic", icon_size, 0);
|
||||
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, down_context, NULL, NULL);
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (icon_info, down_context, NULL, NULL));
|
||||
g_object_unref (icon_info);
|
||||
draw_style_common (down_context, cr, x + width - 2 * button_width, y, button_width, *height,
|
||||
&contents_x, &contents_y, &contents_width, &contents_height);
|
||||
gtk_render_icon (down_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (texture);
|
||||
|
||||
g_object_unref (down_context);
|
||||
|
||||
@@ -241,7 +241,7 @@ realize (GtkWidget *widget)
|
||||
fragment_path = "/glarea/glarea-gl.fs.glsl";
|
||||
}
|
||||
|
||||
init_buffers (&position_buffer, NULL);
|
||||
init_buffers (NULL, &position_buffer);
|
||||
init_shaders (vertex_path, fragment_path, &program, &mvp_location);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ show_page (GtkTextBuffer *buffer,
|
||||
|
||||
gtk_text_buffer_set_text (buffer, "", 0);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
if (page == 1)
|
||||
{
|
||||
gtk_text_buffer_insert (buffer, &iter, "Some text to show that simple ", -1);
|
||||
@@ -73,6 +74,7 @@ show_page (GtkTextBuffer *buffer,
|
||||
"so that related items of information are connected.\n", -1);
|
||||
insert_link (buffer, &iter, "Go back", 1);
|
||||
}
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
}
|
||||
|
||||
/* Looks at all tags covering the position of iter in the text view,
|
||||
@@ -258,6 +260,7 @@ do_hypertext (GtkWidget *do_widget)
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_enable_undo (buffer, TRUE);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
/* Benchmark/Scrolling
|
||||
*
|
||||
* This demo scrolls a view with various content.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static guint tick_cb;
|
||||
static GtkAdjustment *hadjustment;
|
||||
static GtkAdjustment *vadjustment;
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *scrolledwindow;
|
||||
static int selected;
|
||||
|
||||
#define N_WIDGET_TYPES 4
|
||||
|
||||
|
||||
static int hincrement = 5;
|
||||
static int vincrement = 5;
|
||||
|
||||
static gboolean
|
||||
scroll_cb (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer data)
|
||||
{
|
||||
double value;
|
||||
|
||||
value = gtk_adjustment_get_value (vadjustment);
|
||||
if (value + vincrement <= gtk_adjustment_get_lower (vadjustment) ||
|
||||
(value + vincrement >= gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment)))
|
||||
vincrement = - vincrement;
|
||||
|
||||
gtk_adjustment_set_value (vadjustment, value + vincrement);
|
||||
|
||||
value = gtk_adjustment_get_value (hadjustment);
|
||||
if (value + hincrement <= gtk_adjustment_get_lower (hadjustment) ||
|
||||
(value + hincrement >= gtk_adjustment_get_upper (hadjustment) - gtk_adjustment_get_page_size (hadjustment)))
|
||||
hincrement = - hincrement;
|
||||
|
||||
gtk_adjustment_set_value (hadjustment, value + hincrement);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
extern GtkWidget *create_icon (void);
|
||||
|
||||
static void
|
||||
populate_icons (void)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
int top, left;
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
|
||||
g_object_set (grid, "margin", 10, NULL);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
|
||||
|
||||
for (top = 0; top < 100; top++)
|
||||
for (left = 0; left < 15; left++)
|
||||
gtk_grid_attach (GTK_GRID (grid), create_icon (), left, top, 1, 1);
|
||||
|
||||
hincrement = 0;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), grid);
|
||||
}
|
||||
|
||||
static char *content;
|
||||
static gsize content_len;
|
||||
|
||||
extern void fontify (GtkTextBuffer *buffer);
|
||||
|
||||
static void
|
||||
populate_text (gboolean hilight)
|
||||
{
|
||||
GtkWidget *textview;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
if (!content)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
|
||||
content = g_bytes_unref_to_data (bytes, &content_len);
|
||||
}
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, content, (int)content_len);
|
||||
|
||||
if (hilight)
|
||||
fontify (buffer);
|
||||
|
||||
textview = gtk_text_view_new ();
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
|
||||
hincrement = 0;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), textview);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_image (void)
|
||||
{
|
||||
GtkWidget *image;
|
||||
|
||||
if (!content)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
|
||||
content = g_bytes_unref_to_data (bytes, &content_len);
|
||||
}
|
||||
|
||||
image = gtk_picture_new_for_resource ("/sliding_puzzle/portland-rose.jpg");
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
|
||||
|
||||
hincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), image);
|
||||
}
|
||||
|
||||
static void
|
||||
set_widget_type (int type)
|
||||
{
|
||||
if (tick_cb)
|
||||
gtk_widget_remove_tick_callback (window, tick_cb);
|
||||
|
||||
if (gtk_bin_get_child (GTK_BIN (scrolledwindow)))
|
||||
gtk_container_remove (GTK_CONTAINER (scrolledwindow),
|
||||
gtk_bin_get_child (GTK_BIN (scrolledwindow)));
|
||||
|
||||
selected = type;
|
||||
|
||||
switch (selected)
|
||||
{
|
||||
case 0:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling icons");
|
||||
populate_icons ();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling plain text");
|
||||
populate_text (FALSE);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling complex text");
|
||||
populate_text (TRUE);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a big image");
|
||||
populate_image ();
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
tick_cb = gtk_widget_add_tick_callback (window, scroll_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
next_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
int new_index;
|
||||
|
||||
if (selected + 1 >= N_WIDGET_TYPES)
|
||||
new_index = 0;
|
||||
else
|
||||
new_index = selected + 1;
|
||||
|
||||
|
||||
set_widget_type (new_index);
|
||||
}
|
||||
|
||||
static void
|
||||
prev_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
int new_index;
|
||||
|
||||
if (selected - 1 < 0)
|
||||
new_index = N_WIDGET_TYPES - 1;
|
||||
else
|
||||
new_index = selected - 1;
|
||||
|
||||
set_widget_type (new_index);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_iconscroll (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
|
||||
gtk_builder_add_callback_symbols (builder,
|
||||
"next_clicked_cb", G_CALLBACK (next_clicked_cb),
|
||||
"prev_clicked_cb", G_CALLBACK (prev_clicked_cb),
|
||||
NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
scrolledwindow = GTK_WIDGET (gtk_builder_get_object (builder, "scrolledwindow"));
|
||||
gtk_widget_realize (window);
|
||||
hadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hadjustment"));
|
||||
vadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vadjustment"));
|
||||
set_widget_type (0);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="resizable">0</property>
|
||||
<property name="default-width">500</property>
|
||||
<property name="default-height">500</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-start-symbolic</property>
|
||||
<signal name="clicked" handler="prev_clicked_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-end-symbolic</property>
|
||||
<signal name="clicked" handler="next_clicked_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="hadjustment"><object class="GtkAdjustment" id="hadjustment"/></property>
|
||||
<property name="vadjustment"><object class="GtkAdjustment" id="vadjustment"/></property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -68,7 +68,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_INFO);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_INFO");
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
@@ -80,7 +80,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_WARNING);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_WARNING");
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
@@ -94,7 +94,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_QUESTION);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_QUESTION");
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
@@ -106,7 +106,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_ERROR);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_ERROR");
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
@@ -119,7 +119,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_OTHER);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_OTHER");
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
#include "language-names.h"
|
||||
|
||||
#ifndef ISO_CODES_PREFIX
|
||||
#define ISO_CODES_PREFIX "/usr"
|
||||
#endif
|
||||
|
||||
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
|
||||
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ parse_chars (gchar *text,
|
||||
}
|
||||
|
||||
/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
|
||||
static void
|
||||
void
|
||||
fontify (GtkTextBuffer *source_buffer)
|
||||
{
|
||||
GtkTextIter start_iter, next_iter, tmp_iter;
|
||||
@@ -639,7 +639,7 @@ display_nothing (const char *resource)
|
||||
|
||||
str = g_strdup_printf ("The lazy GTK developers forgot to add a way to display the resource '%s'", resource);
|
||||
widget = gtk_label_new (str);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
|
||||
gtk_label_set_wrap (GTK_LABEL (widget), TRUE);
|
||||
|
||||
g_free (str);
|
||||
|
||||
@@ -748,6 +748,9 @@ load_file (const gchar *demoname,
|
||||
|
||||
source_buffer = gtk_text_buffer_new (NULL);
|
||||
|
||||
gtk_text_buffer_begin_irreversible_action (info_buffer);
|
||||
gtk_text_buffer_begin_irreversible_action (source_buffer);
|
||||
|
||||
resource_filename = g_strconcat ("/sources/", filename, NULL);
|
||||
bytes = g_resources_lookup_data (resource_filename, 0, &err);
|
||||
g_free (resource_filename);
|
||||
@@ -880,9 +883,11 @@ load_file (const gchar *demoname,
|
||||
|
||||
fontify (source_buffer);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (source_buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer);
|
||||
g_object_unref (source_buffer);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (info_buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (info_view), info_buffer);
|
||||
g_object_unref (info_buffer);
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@ source_toggled (GtkToggleButton *button)
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_delete (buffer, &start, &end);
|
||||
gtk_text_buffer_insert_markup (buffer, &start, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
g_free (markup);
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), "formatted");
|
||||
@@ -106,11 +108,15 @@ do_markup (GtkWidget *do_widget)
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert_markup (buffer, &iter, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view2));
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert (buffer, &iter, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ demos = files([
|
||||
'drawingarea.c',
|
||||
'dnd.c',
|
||||
'editable_cells.c',
|
||||
'entry_buffer.c',
|
||||
'entry_completion.c',
|
||||
'entry_undo.c',
|
||||
'expander.c',
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
@@ -34,6 +34,7 @@ demos = files([
|
||||
'glarea.c',
|
||||
'headerbar.c',
|
||||
'hypertext.c',
|
||||
'iconscroll.c',
|
||||
'iconview.c',
|
||||
'iconview_edit.c',
|
||||
'images.c',
|
||||
@@ -72,6 +73,7 @@ demos = files([
|
||||
'tabs.c',
|
||||
'tagged_entry.c',
|
||||
'textmask.c',
|
||||
'textundo.c',
|
||||
'textview.c',
|
||||
'textscroll.c',
|
||||
'themes.c',
|
||||
|
||||
@@ -14,34 +14,19 @@
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_a</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Color</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="label">Color</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_b</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Flavors</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="label">Flavors</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_c</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Tools</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="label">Tools</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -57,7 +42,6 @@
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'red'</property>
|
||||
<property name="text">Red</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -65,7 +49,6 @@
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'green'</property>
|
||||
<property name="text">Green</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -73,7 +56,6 @@
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'blue'</property>
|
||||
<property name="text">Blue</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -54,10 +54,7 @@ do_sidebar (GtkWidget *do_widget)
|
||||
stack = gtk_stack_new ();
|
||||
gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN);
|
||||
gtk_stack_sidebar_set_stack (GTK_STACK_SIDEBAR (sidebar), GTK_STACK (stack));
|
||||
|
||||
/* Separator between sidebar and stack */
|
||||
widget = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
|
||||
gtk_container_add (GTK_CONTAINER(box), widget);
|
||||
gtk_widget_set_hexpand (stack, TRUE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), stack);
|
||||
|
||||
@@ -66,6 +63,7 @@ do_sidebar (GtkWidget *do_widget)
|
||||
if (i == 0)
|
||||
{
|
||||
widget = gtk_image_new_from_icon_name ("org.gtk.Demo4");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "icon-dropshadow");
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (widget), 256);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/* Text View/Undo and Redo
|
||||
*
|
||||
* The GtkTextView supports undo and redo through the use of a
|
||||
* GtkTextBuffer. You can enable or disable undo support using
|
||||
* gtk_text_buffer_set_enable_undo().
|
||||
*
|
||||
* Use Primary+Z to undo and Primary+Shift+Z or Primary+Y to
|
||||
* redo previously undone operations.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h> /* for exit() */
|
||||
|
||||
GtkWidget *
|
||||
do_textundo (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *view;
|
||||
GtkWidget *sw;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_default_size (GTK_WINDOW (window),
|
||||
450, 450);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (window), "TextView Undo");
|
||||
|
||||
view = gtk_text_view_new ();
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_enable_undo (buffer, TRUE);
|
||||
|
||||
/* this text cannot be undone */
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_insert (buffer, &iter,
|
||||
"Type to add more text.\n"
|
||||
"Use Primary+Z to undo and Primary+Shift+Z to redo a previously undone action.\n"
|
||||
"\n",
|
||||
-1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (window), sw);
|
||||
gtk_container_add (GTK_CONTAINER (sw), view);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
{
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -128,24 +128,23 @@ insert_text (GtkTextBuffer *buffer)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
GtkTextIter start, end;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkTexture *texture;
|
||||
GtkIconTheme *icon_theme;
|
||||
|
||||
icon_theme = gtk_icon_theme_get_default ();
|
||||
pixbuf = gtk_icon_theme_load_icon (icon_theme,
|
||||
"gtk3-demo",
|
||||
32,
|
||||
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
|
||||
NULL);
|
||||
g_assert (pixbuf);
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
texture = GDK_TEXTURE (gtk_icon_theme_load_icon (icon_theme,
|
||||
"gtk3-demo",
|
||||
32,
|
||||
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
|
||||
NULL));
|
||||
g_assert (texture);
|
||||
|
||||
/* get start of buffer; each insertion will revalidate the
|
||||
* iterator to point to just after the inserted text.
|
||||
*/
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
|
||||
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert (buffer, &iter,
|
||||
"The text widget can display text with all kinds of nifty attributes. "
|
||||
"It also supports multiple views of the same buffer; this demo is "
|
||||
@@ -379,7 +378,8 @@ insert_text (GtkTextBuffer *buffer)
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
|
||||
@@ -81,11 +81,14 @@ get_icon (GtkWidget *image, const gchar *name, gint size)
|
||||
{
|
||||
GtkIconInfo *info;
|
||||
GtkStyleContext *context;
|
||||
GdkTexture *texture;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
context = gtk_widget_get_style_context (image);
|
||||
info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), name, size, 0);
|
||||
pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL);
|
||||
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL));
|
||||
pixbuf = gdk_pixbuf_get_from_texture (texture);
|
||||
g_object_unref (texture);
|
||||
g_object_unref (info);
|
||||
|
||||
return pixbuf;
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
static const char *css =
|
||||
"textview.editor {"
|
||||
" color: rgb(192, 197, 206);"
|
||||
" caret-color: white;"
|
||||
" caret-color: currentColor;"
|
||||
"}"
|
||||
"textview.editor text {"
|
||||
"textview.editor > text {"
|
||||
" background-color: rgb(43, 48, 59);"
|
||||
"}"
|
||||
;
|
||||
|
||||
@@ -1003,6 +1003,9 @@ populate_flowbox (GtkWidget *flowbox)
|
||||
|
||||
while ((name = g_dir_read_name (dir)) != NULL)
|
||||
{
|
||||
if (g_str_has_suffix (name, ".xml"))
|
||||
continue;
|
||||
|
||||
filename = g_build_filename (location, name, NULL);
|
||||
file = g_file_new_for_path (filename);
|
||||
stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
|
||||
@@ -1017,7 +1020,7 @@ populate_flowbox (GtkWidget *flowbox)
|
||||
bd = g_new (BackgroundData, 1);
|
||||
bd->flowbox = flowbox;
|
||||
bd->filename = filename;
|
||||
gdk_pixbuf_new_from_stream_at_scale_async (stream, 110, 110, TRUE, NULL,
|
||||
gdk_pixbuf_new_from_stream_at_scale_async (stream, 110, 110, TRUE, NULL,
|
||||
background_loaded_cb, bd);
|
||||
}
|
||||
|
||||
@@ -1649,7 +1652,7 @@ set_up_context_popover (GtkWidget *widget,
|
||||
GtkWidget *popover = gtk_popover_menu_new_from_model (widget, model);
|
||||
GtkGesture *gesture;
|
||||
|
||||
g_object_set (popover, "has-arrow", FALSE, NULL);
|
||||
gtk_popover_set_has_arrow (GTK_POPOVER (popover), FALSE);
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (clicked_cb), popover);
|
||||
|
||||
@@ -1726,15 +1726,11 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="adjustment">adjustment1</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="opacity">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -1909,11 +1905,11 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="togglesmenuitem">
|
||||
<property name="label">Checks & Radios</property>
|
||||
<object class="GtkMenuItem" id="checksmenuitem">
|
||||
<property name="label">_Checks</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="togglessubmenu">
|
||||
<object class="GtkMenu" id="checkssubmenu">
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="checkmenuitem1">
|
||||
<property name="label">_Check</property>
|
||||
@@ -1957,9 +1953,16 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="radiosmenuitem">
|
||||
<property name="label">_Radios</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="radiossubmenu">
|
||||
<child>
|
||||
<object class="GtkRadioMenuItem" id="radiomenuitem1">
|
||||
<property name="label">_Radio</property>
|
||||
@@ -2011,6 +2014,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
FOO
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem3">
|
||||
<property name="label" translatable="yes">View</property>
|
||||
@@ -2118,7 +2122,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkInfoBar" id="infobar">
|
||||
<property name="visible">0</property>
|
||||
<property name="show-close-button">1</property>
|
||||
<child internal-child="content_area">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@@ -2129,9 +2133,14 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="shadow-type">none</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="MyTextView" id="text3">
|
||||
@@ -2145,6 +2154,11 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="statusbar"/>
|
||||
</child>
|
||||
@@ -3592,21 +3606,18 @@ bad things might happen.</property>
|
||||
<object class="GtkModelButton">
|
||||
<property name="icon"><object class="GThemedIcon"><property name="name">edit-cut-symbolic</property></object></property>
|
||||
<property name="iconic">1</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="icon"><object class="GThemedIcon"><property name="name">edit-copy-symbolic</property></object></property>
|
||||
<property name="iconic">1</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="icon"><object class="GThemedIcon"><property name="name">edit-paste-symbolic</property></object></property>
|
||||
<property name="iconic">1</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -3944,7 +3955,7 @@ bad things might happen.</property>
|
||||
</section>
|
||||
<section>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">Checks & Radios</attribute>
|
||||
<attribute name="label" translatable="yes">C_hecks</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Check</attribute>
|
||||
@@ -3968,6 +3979,9 @@ bad things might happen.</property>
|
||||
<attribute name="hidden-when">action-missing</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Radios</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Radio</attribute>
|
||||
|
||||
@@ -76,10 +76,10 @@ How to compile GTK itself
|
||||
</para>
|
||||
<para>
|
||||
Several environment variables are useful to pass to set before
|
||||
running configure. <envar>CPPFLAGS</envar> contains options to
|
||||
pass to the C compiler, and is used to tell the compiler where
|
||||
to look for include files. The <envar>LDFLAGS</envar> variable
|
||||
is used in a similar fashion for the linker. Finally the
|
||||
running <application>meson</application>. <envar>CPPFLAGS</envar>
|
||||
contains options to pass to the C compiler, and is used to tell
|
||||
the compiler where to look for include files. The <envar>LDFLAGS</envar>
|
||||
variable is used in a similar fashion for the linker. Finally the
|
||||
<envar>PKG_CONFIG_PATH</envar> environment variable contains
|
||||
a search path that <command>pkg-config</command> (see below)
|
||||
uses when looking for files describing how to compile
|
||||
@@ -106,6 +106,61 @@ How to compile GTK itself
|
||||
export LD_LIBRARY_PATH PATH
|
||||
</programlisting>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="build-types">
|
||||
<title>Build types</title>
|
||||
|
||||
<para>Meson has different build types, exposed by the <literal>buildtype</literal>
|
||||
configuration option. GTK enables and disables functionality depending on
|
||||
the build type used when calling <application>meson</application> to
|
||||
configure the build.</para>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>debug</systemitem> and <systemitem>debugoptimized</systemitem></title>
|
||||
|
||||
<para>
|
||||
GTK will enable debugging code paths in both the
|
||||
<literal>debug</literal> and <literal>debugoptimized</literal>
|
||||
build types. Builds with <literal>buildtype</literal> set
|
||||
to <literal>debug</literal> will additionally enable
|
||||
consistency checks on the internal state of the toolkit.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is recommended to use the <literal>debug</literal> or
|
||||
<literal>debugoptimized</literal> build types when developing
|
||||
GTK itself. Additionally, <literal>debug</literal> builds of
|
||||
GTK are recommended for profiling and debugging GTK applications,
|
||||
as they include additional validation of the internal state.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <literal>debugoptimized</literal> build type is the
|
||||
default for GTK if no build type is specified when calling
|
||||
<application>meson</application>
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>release</systemitem></title>
|
||||
|
||||
<para>
|
||||
The <literal>release</literal> build type will disable
|
||||
debugging code paths and additional run time safeties, like
|
||||
checked casts for object instances.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<para>
|
||||
The <literal>plain</literal> build type provided by Meson
|
||||
should only be used when packaging GTK, and it's expected
|
||||
that packagers will provide their own compiler flags when
|
||||
building GTK. See the previous section for the list of
|
||||
environment variables to be used to define compiler and
|
||||
linker flags.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="dependencies">
|
||||
<title>Dependencies</title>
|
||||
<para>
|
||||
@@ -283,184 +338,181 @@ How to compile GTK itself
|
||||
See <xref linkend="gtk-resources"/> for more information.
|
||||
</para>
|
||||
</refsect1>
|
||||
<refsect1 id="extra-configuration-options">
|
||||
<title>Extra Configuration Options</title>
|
||||
|
||||
<refsect1 id="extra-configuration-options">
|
||||
<title>Extra Configuration Options</title>
|
||||
|
||||
<para>
|
||||
In addition to the normal options provided by Meson, GTK defines
|
||||
various arguments that modify what should be built.
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>meson</command>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dx11-backend=true</arg>
|
||||
<arg choice="plain">-Dx11-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwayland-backend=true</arg>
|
||||
<arg choice="plain">-Dwayland-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dbroadway-backend=true</arg>
|
||||
<arg choice="plain">-Dbroadway-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwin32-backend=true</arg>
|
||||
<arg choice="plain">-Dwin32-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dquartz-backend=true</arg>
|
||||
<arg choice="plain">-Dquartz-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dmedia=gstreamer</arg>
|
||||
<arg choice="plain">-Dmedia=ffmpeg</arg>
|
||||
<arg choice="plain">-Dmedia=all</arg>
|
||||
<arg choice="plain">-Dmedia=none</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dvulkan=yes</arg>
|
||||
<arg choice="plain">-Dvulkan=no</arg>
|
||||
<arg choice="plain">-Dvulkan=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dxinerama=yes</arg>
|
||||
<arg choice="plain">-Dxinerama=no</arg>
|
||||
<arg choice="plain">-Dxinerama=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcloudproviders=true</arg>
|
||||
<arg choice="plain">-Dcloudproviders=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dprint-backends=all</arg>
|
||||
<arg choice="plain">-Dprint-backends=none</arg>
|
||||
<arg choice="plain">-Dprint-backends=cups,lpr,...</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcolord=yes</arg>
|
||||
<arg choice="plain">-Dcolord=no</arg>
|
||||
<arg choice="plain">-Dcolord=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dgtk_doc=true</arg>
|
||||
<arg choice="plain">-Dgtk_doc=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dman-pages=true</arg>
|
||||
<arg choice="plain">-Dman-pages=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dintrospection=true</arg>
|
||||
<arg choice="plain">-Dintrospection=false</arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
</para>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>xinerama</systemitem></title>
|
||||
|
||||
<para>
|
||||
In addition to the normal options provided by Meson, GTK defines
|
||||
various arguments that modify what should be built.
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>meson</command>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dx11-backend=true</arg>
|
||||
<arg choice="plain">-Dx11-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwayland-backend=true</arg>
|
||||
<arg choice="plain">-Dwayland-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dbroadway-backend=true</arg>
|
||||
<arg choice="plain">-Dbroadway-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dwin32-backend=true</arg>
|
||||
<arg choice="plain">-Dwin32-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dquartz-backend=true</arg>
|
||||
<arg choice="plain">-Dquartz-backend=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dmedia=gstreamer</arg>
|
||||
<arg choice="plain">-Dmedia=ffmpeg</arg>
|
||||
<arg choice="plain">-Dmedia=all</arg>
|
||||
<arg choice="plain">-Dmedia=none</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dvulkan=yes</arg>
|
||||
<arg choice="plain">-Dvulkan=no</arg>
|
||||
<arg choice="plain">-Dvulkan=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dxinerama=yes</arg>
|
||||
<arg choice="plain">-Dxinerama=no</arg>
|
||||
<arg choice="plain">-Dxinerama=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcloudproviders=true</arg>
|
||||
<arg choice="plain">-Dcloudproviders=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dprint-backends=all</arg>
|
||||
<arg choice="plain">-Dprint-backends=none</arg>
|
||||
<arg choice="plain">-Dprint-backends=cups,lpr,...</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dcolord=yes</arg>
|
||||
<arg choice="plain">-Dcolord=no</arg>
|
||||
<arg choice="plain">-Dcolord=auto</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dgtk_doc=true</arg>
|
||||
<arg choice="plain">-Dgtk_doc=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dman-pages=true</arg>
|
||||
<arg choice="plain">-Dman-pages=false</arg>
|
||||
</group>
|
||||
<sbr/>
|
||||
<group>
|
||||
<arg choice="plain">-Dintrospection=true</arg>
|
||||
<arg choice="plain">-Dintrospection=false</arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
By default GTK will try to link against the Xinerama libraries
|
||||
if they are found. This options can be used to explicitly control
|
||||
whether Xinerama should be used.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>xinerama</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>gtk_doc</systemitem> and
|
||||
<systemitem>man-pages</systemitem></title>
|
||||
|
||||
<para>
|
||||
By default GTK will try to link against the Xinerama libraries
|
||||
if they are found. This options can be used to explicitly control
|
||||
whether Xinerama should be used.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
The <application>gtk-doc</application> package is
|
||||
used to generate the reference documentation included
|
||||
with GTK. By default support for <application>gtk-doc</application>
|
||||
is disabled because it requires various extra dependencies
|
||||
to be installed. If you have
|
||||
<application>gtk-doc</application> installed and
|
||||
are modifying GTK, you may want to enable
|
||||
<application>gtk-doc</application> support by passing
|
||||
in <systemitem>gtk_doc</systemitem>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, some tools provided by GTK have their own
|
||||
manual pages generated using a similar set of dependencies;
|
||||
if you have <application>xsltproc</application> then you
|
||||
can generate manual pages by passing <systemitem>man-pages</systemitem>
|
||||
when configuring the build.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>gtk_doc</systemitem> and
|
||||
<systemitem>man-pages</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>print-backends</systemitem></title>
|
||||
|
||||
<para>
|
||||
The <application>gtk-doc</application> package is
|
||||
used to generate the reference documentation included
|
||||
with GTK. By default support for <application>gtk-doc</application>
|
||||
is disabled because it requires various extra dependencies
|
||||
to be installed. If you have
|
||||
<application>gtk-doc</application> installed and
|
||||
are modifying GTK, you may want to enable
|
||||
<application>gtk-doc</application> support by passing
|
||||
in <systemitem>gtk_doc</systemitem>.
|
||||
</para>
|
||||
<para>
|
||||
Additionally, some tools provided by GTK have their own
|
||||
manual pages generated using a similar set of dependencies;
|
||||
if you have <application>xsltproc</application> then you
|
||||
can generate manual pages by passing <systemitem>man-pages</systemitem>
|
||||
when configuring the build.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
By default, GTK will try to build various print backends if
|
||||
their dependencies are found. This option can be used to
|
||||
explicitly control which print backends should be built.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>print-backends</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>x11-backend</systemitem>,
|
||||
<systemitem>win32-backend</systemitem>,
|
||||
<systemitem>quartz-backend</systemitem>,
|
||||
<systemitem>broadway-backend</systemitem> and
|
||||
<systemitem>wayland-backend</systemitem></title>
|
||||
|
||||
<para>
|
||||
By default, GTK will try to build various print backends if
|
||||
their dependencies are found. This option can be used to
|
||||
explicitly control which print backends should be built.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
Enable specific backends for GDK. If none of these options
|
||||
are given, the Wayland backend will be enabled by default,
|
||||
if the platform is Linux; the X11 backend will also be enabled
|
||||
by default, unless the platform is Windows, in which case the
|
||||
default is win32, or the platform is macOS, in which case the
|
||||
default is quartz. If any backend is explicitly enabled or disabled,
|
||||
no other platform will be enabled automatically.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>x11-backend</systemitem>,
|
||||
<systemitem>win32-backend</systemitem>,
|
||||
<systemitem>quartz-backend</systemitem>,
|
||||
<systemitem>broadway-backend</systemitem> and
|
||||
<systemitem>wayland-backend</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>introspection</systemitem></title>
|
||||
|
||||
<para>
|
||||
Enable specific backends for GDK. If none of these options
|
||||
are given, the Wayland backend will be enabled by default,
|
||||
if the platform is Linux; the X11 backend will also be enabled
|
||||
by default, unless the platform is Windows, in which case the
|
||||
default is win32, or the platform is macOS, in which case the
|
||||
default is quartz. If any backend is explicitly enabled or disabled,
|
||||
no other platform will be enabled automatically.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
Allows to disable building introspection support. This is option
|
||||
is mainly useful for shortening turnaround times on developer
|
||||
systems. Installed builds of GTK should always have introspection
|
||||
support.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>introspection</systemitem></title>
|
||||
<formalpara>
|
||||
<title><systemitem>build-tests</systemitem>,
|
||||
<systemitem>install-tests</systemitem>,
|
||||
<systemitem>demos</systemitem></title>
|
||||
|
||||
<para>
|
||||
Allows to disable building introspection support. This is option
|
||||
is mainly useful for shortening turnaround times on developer
|
||||
systems. Installed builds of GTK should always have introspection
|
||||
support.
|
||||
</para>
|
||||
</formalpara>
|
||||
<para>
|
||||
By default, GTK will build quite a few tests and demos.
|
||||
While these are useful on a developer system, they are not
|
||||
needed when GTK is built e.g. for a flatpak runtime. These
|
||||
options allow to disable building tests and demos.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
<formalpara>
|
||||
<title><systemitem>build-tests</systemitem>,
|
||||
<systemitem>install-tests</systemitem>,
|
||||
<systemitem>demos</systemitem></title>
|
||||
|
||||
<para>
|
||||
By default, GTK will build quite a few tests and demos.
|
||||
While these are useful on a developer system, they are not
|
||||
needed when GTK is built e.g. for a flatpak runtime. These
|
||||
options allow to disable building tests and demos.
|
||||
</para>
|
||||
</formalpara>
|
||||
|
||||
</refsect1>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
<!-- Local Variables: -->
|
||||
<!-- sgml-parent-document: ("gtk-docs.sgml" "chapter" "refentry") -->
|
||||
<!-- End: -->
|
||||
@@ -224,10 +224,3 @@
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: xml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "refentry")
|
||||
End:
|
||||
-->
|
||||
|
||||
@@ -364,10 +364,3 @@
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossary>
|
||||
|
||||
<!--
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: ("gtk-docs.sgml" "book" "glossary")
|
||||
End:
|
||||
-->
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
<title>GTK Overview</title>
|
||||
<xi:include href="overview.xml"/>
|
||||
<xi:include href="xml/getting_started.xml"/>
|
||||
<xi:include href="resources.sgml" />
|
||||
<xi:include href="xml/question_index.sgml" />
|
||||
<xi:include href="resources.xml" />
|
||||
<xi:include href="xml/question_index.xml" />
|
||||
<xi:include href="xml/drawing-model.xml" />
|
||||
<xi:include href="xml/input-handling.xml" />
|
||||
<xi:include href="xml/actions.xml" />
|
||||
@@ -51,6 +51,7 @@
|
||||
<xi:include href="xml/gtksortlistmodel.xml" />
|
||||
<xi:include href="xml/gtktreelistmodel.xml" />
|
||||
<xi:include href="xml/gtkselectionmodel.xml" />
|
||||
<xi:include href="xml/gtknoselection.xml" />
|
||||
<xi:include href="xml/gtksingleselection.xml" />
|
||||
</chapter>
|
||||
|
||||
@@ -167,7 +168,7 @@
|
||||
|
||||
<chapter id="TextWidgetObjects">
|
||||
<title>Multiline Text Editor</title>
|
||||
<xi:include href="xml/text_widget.sgml" />
|
||||
<xi:include href="xml/text_widget.xml" />
|
||||
<xi:include href="xml/gtktextiter.xml" />
|
||||
<xi:include href="xml/gtktextmark.xml" />
|
||||
<xi:include href="xml/gtktextbuffer.xml" />
|
||||
@@ -178,7 +179,7 @@
|
||||
|
||||
<chapter id="TreeWidgetObjects">
|
||||
<title>Tree, List and Icon Grid Widgets</title>
|
||||
<xi:include href="xml/tree_widget.sgml" />
|
||||
<xi:include href="xml/tree_widget.xml" />
|
||||
<xi:include href="xml/gtktreemodel.xml" />
|
||||
<xi:include href="xml/gtktreeselection.xml" />
|
||||
<xi:include href="xml/gtktreeviewcolumn.xml" />
|
||||
@@ -406,12 +407,12 @@
|
||||
|
||||
<part id="platform-support">
|
||||
<title>GTK Platform Support</title>
|
||||
<xi:include href="building.sgml" />
|
||||
<xi:include href="xml/compiling.sgml" />
|
||||
<xi:include href="running.sgml" />
|
||||
<xi:include href="x11.sgml" />
|
||||
<xi:include href="windows.sgml" />
|
||||
<xi:include href="osx.sgml" />
|
||||
<xi:include href="building.xml" />
|
||||
<xi:include href="xml/compiling.xml" />
|
||||
<xi:include href="running.xml" />
|
||||
<xi:include href="x11.xml" />
|
||||
<xi:include href="windows.xml" />
|
||||
<xi:include href="osx.xml" />
|
||||
<xi:include href="broadway.xml" />
|
||||
<xi:include href="wayland.xml" />
|
||||
</part>
|
||||
|
||||
@@ -341,6 +341,30 @@ GTK_CENTER_BOX_GET_CLASS
|
||||
gtk_center_box_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkcenterlayout</FILE>
|
||||
<TITLE>GtkCenterLayout</TITLE>
|
||||
GtkCenterLayout
|
||||
gtk_center_layout_new
|
||||
gtk_center_layout_set_start_widget
|
||||
gtk_center_layout_set_center_widget
|
||||
gtk_center_layout_set_end_widget
|
||||
gtk_center_layout_get_start_widget
|
||||
gtk_center_layout_get_center_widget
|
||||
gtk_center_layout_get_end_widget
|
||||
gtk_center_layout_set_baseline_position
|
||||
gtk_center_layout_get_baseline_position
|
||||
<SUBSECTION Private>
|
||||
GTK_TYPE_CENTER_layout
|
||||
GTK_CENTER_LAYOUT
|
||||
GTK_CENTER_LAYOUT_CLASS
|
||||
GTK_IS_CENTER_LAYOUT
|
||||
GTK_IS_CENTER_LAYOUT_CLASS
|
||||
GTK_CENTER_LAYOUT_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
gtk_center_layout_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtklistbox</FILE>
|
||||
<TITLE>GtkListBox</TITLE>
|
||||
@@ -441,12 +465,23 @@ GTK_TYPE_SELECTION_MODEL
|
||||
gtk_selection_model_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtknoselection</FILE>
|
||||
<TITLE>GtkNoSelection</TITLE>
|
||||
GtkNoSelection
|
||||
gtk_no_selection_new
|
||||
gtk_no_selection_get_model
|
||||
<SUBSECTION Private>
|
||||
gtk_no_selection_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtksingleselection</FILE>
|
||||
<TITLE>GtkSingleSelection</TITLE>
|
||||
GtkSingleSelection
|
||||
GTK_INVALID_LIST_POSITION
|
||||
gtk_single_selection_new
|
||||
gtk_single_selection_get_model
|
||||
gtk_single_selection_get_selected
|
||||
gtk_single_selection_set_selected
|
||||
gtk_single_selection_get_selected_item
|
||||
@@ -847,6 +882,8 @@ gtk_editable_get_width_chars
|
||||
gtk_editable_set_width_chars
|
||||
gtk_editable_get_max_width_chars
|
||||
gtk_editable_set_max_width_chars
|
||||
gtk_editable_get_enable_undo
|
||||
gtk_editable_set_enable_undo
|
||||
<SUBSECTION>
|
||||
gtk_editable_install_properties
|
||||
gtk_editable_init_delegate
|
||||
@@ -1684,8 +1721,8 @@ gtk_label_set_yalign
|
||||
gtk_label_set_ellipsize
|
||||
gtk_label_set_width_chars
|
||||
gtk_label_set_max_width_chars
|
||||
gtk_label_set_line_wrap
|
||||
gtk_label_set_line_wrap_mode
|
||||
gtk_label_set_wrap
|
||||
gtk_label_set_wrap_mode
|
||||
gtk_label_set_lines
|
||||
gtk_label_get_layout_offsets
|
||||
gtk_label_get_mnemonic_keyval
|
||||
@@ -1705,8 +1742,8 @@ gtk_label_get_width_chars
|
||||
gtk_label_get_max_width_chars
|
||||
gtk_label_get_label
|
||||
gtk_label_get_layout
|
||||
gtk_label_get_line_wrap
|
||||
gtk_label_get_line_wrap_mode
|
||||
gtk_label_get_wrap
|
||||
gtk_label_get_wrap_mode
|
||||
gtk_label_get_lines
|
||||
gtk_label_get_mnemonic_widget
|
||||
gtk_label_get_selection_bounds
|
||||
@@ -1787,6 +1824,8 @@ gtk_map_list_model_get_type
|
||||
GtkMenu
|
||||
gtk_menu_new
|
||||
gtk_menu_new_from_model
|
||||
GtkPopoverMenuFlags
|
||||
gtk_menu_new_from_model_full
|
||||
gtk_menu_reorder_child
|
||||
gtk_menu_popup_at_rect
|
||||
gtk_menu_popup_at_widget
|
||||
@@ -1866,6 +1905,7 @@ gtk_menu_button_set_relief
|
||||
gtk_menu_button_get_relief
|
||||
gtk_menu_button_popup
|
||||
gtk_menu_button_popdown
|
||||
gtk_menu_button_set_create_popup_func
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_MENU_BUTTON
|
||||
GTK_MENU_BUTTON
|
||||
@@ -2838,6 +2878,18 @@ gtk_text_buffer_begin_user_action
|
||||
gtk_text_buffer_end_user_action
|
||||
gtk_text_buffer_add_selection_clipboard
|
||||
gtk_text_buffer_remove_selection_clipboard
|
||||
gtk_text_buffer_get_can_undo
|
||||
gtk_text_buffer_get_can_redo
|
||||
gtk_text_buffer_get_enable_undo
|
||||
gtk_text_buffer_set_enable_undo
|
||||
gtk_text_buffer_get_max_undo_levels
|
||||
gtk_text_buffer_set_max_undo_levels
|
||||
gtk_text_buffer_undo
|
||||
gtk_text_buffer_redo
|
||||
gtk_text_buffer_begin_irreversible_action
|
||||
gtk_text_buffer_end_irreversible_action
|
||||
gtk_text_buffer_begin_user_action
|
||||
gtk_text_buffer_end_user_action
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TEXT_BUFFER
|
||||
@@ -3043,7 +3095,7 @@ gtk_text_view_get_line_at_y
|
||||
gtk_text_view_get_line_yrange
|
||||
gtk_text_view_get_iter_at_location
|
||||
gtk_text_view_get_iter_at_position
|
||||
gtk_text_view_buffer_to_surface_coords
|
||||
gtk_text_view_buffer_to_window_coords
|
||||
gtk_text_view_window_to_buffer_coords
|
||||
gtk_text_view_set_border_window_size
|
||||
gtk_text_view_get_border_window_size
|
||||
@@ -3058,8 +3110,10 @@ GtkTextChildAnchor
|
||||
gtk_text_child_anchor_new
|
||||
gtk_text_child_anchor_get_widgets
|
||||
gtk_text_child_anchor_get_deleted
|
||||
gtk_text_view_add_child_in_window
|
||||
gtk_text_view_move_child
|
||||
gtk_text_view_get_gutter
|
||||
gtk_text_view_set_gutter
|
||||
gtk_text_view_add_overlay
|
||||
gtk_text_view_move_overlay
|
||||
gtk_text_view_set_wrap_mode
|
||||
gtk_text_view_get_wrap_mode
|
||||
gtk_text_view_set_editable
|
||||
@@ -4815,13 +4869,6 @@ gtk_get_event_target
|
||||
gtk_get_event_target_with_type
|
||||
gtk_propagate_event
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_set_supported_themes
|
||||
gtk_set_unsupported_themes
|
||||
gtk_set_prefer_dark_theme
|
||||
gtk_get_current_theme
|
||||
gtk_theme_is_dark
|
||||
|
||||
<SUBSECTION Private>
|
||||
gtk_init_abi_check
|
||||
gtk_init_check_abi_check
|
||||
@@ -5214,6 +5261,10 @@ gtk_binding_set_find
|
||||
gtk_bindings_activate
|
||||
gtk_bindings_activate_event
|
||||
gtk_binding_set_activate
|
||||
gtk_binding_entry_add_action
|
||||
gtk_binding_entry_add_action_variant
|
||||
GtkBindingCallback
|
||||
gtk_binding_entry_add_callback
|
||||
gtk_binding_entry_add_signal
|
||||
gtk_binding_entry_add_signal_from_string
|
||||
gtk_binding_entry_skip
|
||||
@@ -5271,12 +5322,9 @@ gtk_icon_theme_lookup_by_gicon
|
||||
gtk_icon_theme_lookup_by_gicon_for_scale
|
||||
gtk_icon_theme_load_icon
|
||||
gtk_icon_theme_load_icon_for_scale
|
||||
gtk_icon_theme_list_contexts
|
||||
gtk_icon_theme_list_icons
|
||||
gtk_icon_theme_get_icon_sizes
|
||||
gtk_icon_theme_get_example_icon_name
|
||||
gtk_icon_theme_rescan_if_needed
|
||||
gtk_icon_info_new_for_pixbuf
|
||||
gtk_icon_info_get_base_size
|
||||
gtk_icon_info_get_base_scale
|
||||
gtk_icon_info_get_filename
|
||||
@@ -6707,6 +6755,8 @@ gtk_event_controller_key_forward
|
||||
gtk_event_controller_key_get_group
|
||||
gtk_event_controller_key_get_focus_origin
|
||||
gtk_event_controller_key_get_focus_target
|
||||
gtk_event_controller_key_contains_focus
|
||||
gtk_event_controller_key_is_focus
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_EVENT_CONTROLLER_KEY
|
||||
|
||||
@@ -123,6 +123,7 @@ gtk_menu_tool_button_get_type
|
||||
gtk_message_dialog_get_type
|
||||
gtk_model_button_get_type
|
||||
gtk_mount_operation_get_type
|
||||
gtk_native_get_type
|
||||
gtk_notebook_get_type
|
||||
gtk_notebook_page_get_type
|
||||
gtk_orientable_get_type
|
||||
|
||||
@@ -342,8 +342,8 @@ images = [
|
||||
content_files = [
|
||||
'actions.xml',
|
||||
'broadway.xml',
|
||||
'building.sgml',
|
||||
'compiling.sgml',
|
||||
'building.xml',
|
||||
'compiling.xml',
|
||||
'css-overview.xml',
|
||||
'css-properties.xml',
|
||||
'drawing-model.xml',
|
||||
@@ -361,31 +361,31 @@ content_files = [
|
||||
'input-handling.xml',
|
||||
'migrating-2to4.xml',
|
||||
'migrating-3to4.xml',
|
||||
'osx.sgml',
|
||||
'other_software.sgml',
|
||||
'osx.xml',
|
||||
'other_software.xml',
|
||||
'overview.xml',
|
||||
'question_index.sgml',
|
||||
'resources.sgml',
|
||||
'running.sgml',
|
||||
'text_widget.sgml',
|
||||
'tree_widget.sgml',
|
||||
'question_index.xml',
|
||||
'resources.xml',
|
||||
'running.xml',
|
||||
'text_widget.xml',
|
||||
'tree_widget.xml',
|
||||
'visual_index.xml',
|
||||
'wayland.xml',
|
||||
'windows.sgml',
|
||||
'x11.sgml',
|
||||
'windows.xml',
|
||||
'x11.xml',
|
||||
]
|
||||
|
||||
expand_content_files = [
|
||||
'actions.xml',
|
||||
'compiling.sgml',
|
||||
'compiling.xml',
|
||||
'drawing-model.xml',
|
||||
'glossary.xml',
|
||||
'input-handling.xml',
|
||||
'migrating-2to4.xml',
|
||||
'migrating-3to4.xml',
|
||||
'question_index.sgml',
|
||||
'text_widget.sgml',
|
||||
'tree_widget.sgml',
|
||||
'question_index.xml',
|
||||
'text_widget.xml',
|
||||
'tree_widget.xml',
|
||||
]
|
||||
|
||||
types_conf = configuration_data()
|
||||
|
||||
@@ -813,6 +813,21 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>GtkEntryBuffer ::deleted-text has changed</title>
|
||||
<para>
|
||||
To allow signal handlers to access the deleted text before it
|
||||
has been deleted #GtkEntryBuffer::deleted-text has changed from
|
||||
%G_SIGNAL_RUN_FIRST to %G_SIGNAL_RUN_LAST. The default handler
|
||||
removes the text from the #GtkEntryBuffer.
|
||||
</para>
|
||||
<para>
|
||||
To adapt existing code, use g_signal_connect_after() or
|
||||
%G_CONNECT_AFTER when using g_signal_connect_data() or
|
||||
g_signal_connect_object().
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -112,6 +112,16 @@ multiple bytes in UTF-8, and the two-character sequence "\r\n" is also
|
||||
considered a line separator.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Text buffers support undo and redo if gtk_text_buffer_set_undo_enabled()
|
||||
has been set to %TRUE. Use gtk_text_buffer_undo() or gtk_text_buffer_redo()
|
||||
to perform the necessary action. Note that these operations are ignored if
|
||||
the buffer is not editable. Developers may want some operations to not be
|
||||
undoable. To do this, wrap your changes in
|
||||
gtk_text_buffer_begin_irreversible_action() and
|
||||
gtk_text_buffer_end_irreversible_action().
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
HANDLING WIDGET STYLES
|
||||
======================
|
||||
|
||||
|
||||
A widget gets created with a default style.
|
||||
The global default style can be affected by gtk_widget_set_default_style()
|
||||
and can be queried by gtk_widget_get_default_style().
|
||||
The initial style that is assigned to a widget as default style upon
|
||||
creation can be affected by wrapping the widget's creation as follows:
|
||||
gtk_widget_push_style (my_style);
|
||||
widget = gtk_type_new (gtk_button_get_type ());
|
||||
gtk_widget_pop_style ();
|
||||
|
||||
There are certain functions to affect widget styles after a widget's
|
||||
creation:
|
||||
|
||||
gtk_widget_set_style ()
|
||||
Save the default style and set a user style.
|
||||
This will override a previously set user style or
|
||||
previously set rc styles.
|
||||
|
||||
gtk_widget_reset_rc_styles ()
|
||||
Descends through a widget hierarchy and sets the rc style
|
||||
on all widgets that don't have a user style set.
|
||||
|
||||
gtk_widget_ensure_style ()
|
||||
Ensure that the widget either has a user style set, or an rc lookup
|
||||
has been performed.
|
||||
|
||||
gtk_rc_get_style ()
|
||||
Return an rc style for a widget if there is one.
|
||||
|
||||
gtk_widget_set_name ()
|
||||
Change widget name, and perform a new rc lookup if no user style
|
||||
is set.
|
||||
|
||||
gtk_widget_realize ()
|
||||
Besides realizing the widget this function will:
|
||||
- perform an rc lookup if necessary,
|
||||
- attach a widget's style.
|
||||
|
||||
gtk_widget_get_style ()
|
||||
Return a widgets style, this function will perform an rc lookup
|
||||
if necessary.
|
||||
|
||||
gtk_widget_set_parent ()
|
||||
This function will perform rc lookups recursively for all widgets
|
||||
that do not have a user style set.
|
||||
|
||||
gtk_style_copy ()
|
||||
This function can be used to copy a widget's style.
|
||||
The style can subsequently be changed (e.g., by modifications to the
|
||||
red/green/blue values of a certain color) and then be applied to the
|
||||
widget via gtk_widget_set_style().
|
||||
|
||||
|
||||
GtkWidget::style_set
|
||||
This signal will be emitted for a widget once its style changes with
|
||||
an additional argument previous_style which will hold the widget->style
|
||||
value from a previous emission.
|
||||
The initial emission of this signal is guaranteed to happen prior
|
||||
to any GtkWidget::size_request emission, and will have the previous_style
|
||||
argument set to NULL.
|
||||
The GtkWidgetClass implements a default handler for this signal that
|
||||
will set the widget's window's background of widgets that provide their
|
||||
own windows according to the new style.
|
||||
Derived widgets need to override this default handler, if:
|
||||
- their size requisition depends on the current style.
|
||||
(e.g., on the style's fonts)
|
||||
- they set the background of widget->window to something other than.
|
||||
style->bg. (e.g., GtkListItem)
|
||||
- the widget provides windows other than widget->window.
|
||||
- the widget has any other stored dependencies on the style.
|
||||
|
||||
|
||||
|
||||
Flag indications:
|
||||
|
||||
!GTK_RC_STYLE && !GTK_USER_STYLE:
|
||||
The widget has its default style set, no rc lookup has been
|
||||
performed, the widget has not been size requested yet and is
|
||||
therefore not yet realized.
|
||||
|
||||
GTK_USER_STYLE:
|
||||
GTK_RC_STYLE is not set.
|
||||
The widget has a user style assigned, and its default style has been
|
||||
saved.
|
||||
|
||||
GTK_RC_STYLE:
|
||||
GTK_USER_STYLE is not set.
|
||||
If the widget has a saved default style, it has been assigned an
|
||||
rc style. If the widget does not have a saved default style, it still
|
||||
has its default style but an rc lookup has already been performed.
|
||||
|
||||
|
||||
- Tim Janik <timj@gimp.org>
|
||||
1998/02/27
|
||||
@@ -1,836 +0,0 @@
|
||||
This file is some notes about how different widgets are drawn.
|
||||
|
||||
=============
|
||||
|
||||
GtkMenu
|
||||
|
||||
=============
|
||||
+----------------------------------------------------------------------------+
|
||||
| A |
|
||||
| +------------------------------------------------------------------------+ |
|
||||
| |############################# C ########################################| |
|
||||
| |# D #| |
|
||||
| |# +-------------------------------------------------------------------+#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | Item 1 |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# +-------------------------------------------------------------------+#| |
|
||||
| |# +-------------------------------------------------------------------+#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
|A|B | |B|A|
|
||||
| |# | Item 2 |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# +-------------------------------------------------------------------+#| |
|
||||
| |# [...] #| |
|
||||
| |# +-------------------------------------------------------------------+#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | Item n |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# | |#| |
|
||||
| |# +-------------------------------------------------------------------+#| |
|
||||
| |# D #| |
|
||||
| |############################# C ########################################| |
|
||||
| +------------------------------------------------------------------------| |
|
||||
| A |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: xthickness
|
||||
C: ythickness
|
||||
D: vertical_padding
|
||||
|
||||
=============
|
||||
|
||||
GtkMenuItem
|
||||
|
||||
=============
|
||||
|
||||
+----------------------------------------------------------------------------+
|
||||
| A |
|
||||
| +------------------------------------------------------------------------+ |
|
||||
| |############################# C ########################################| |
|
||||
| |#+-+------------+--+-------------------------------+--+-------------+-+#| |
|
||||
| |#| |\\\\\\\\\\\\| | /|\ |**| | |#| |
|
||||
| |#| |<------E------>| | |**| G | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| >> | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| >>>> | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| >>>>>> | |#| |
|
||||
|A|B|D|\\\\\\\\\\\\| F| Child G |*H| >>>>>>>> |D|B|A|
|
||||
| |#| |\\\\\\\\\\\\| | | |**| >>>>>> | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| >>>> | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| >> | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | | |**| | |#| |
|
||||
| |#| |\\\\\\\\\\\\| | \|/ |**| | |#| |
|
||||
| |#+-+------------+--+-------------------------------+--+-------------+-+#| |
|
||||
| |############################# C ########################################| |
|
||||
| +------------------------------------------------------------------------+ |
|
||||
| A |
|
||||
+----------------------------------------------------------------------------+
|
||||
|
||||
A: GtkContainer:border_width
|
||||
B: xthickness
|
||||
C: ythickness
|
||||
D: horizontal_padding
|
||||
E: toggle_size
|
||||
F: toggle_spacing
|
||||
G: Requested height of child (also used for width of arrow
|
||||
H: arrow_spacing spacing (when the item has a non-vertical submenu)
|
||||
|
||||
|
||||
=============
|
||||
|
||||
GtkOptionMenu:
|
||||
|
||||
=============
|
||||
|
||||
Geometry parameters
|
||||
|
||||
Style properties
|
||||
|
||||
GtkWidget::interior_focus = TRUE
|
||||
GtkWidget::focus_width = 1
|
||||
GtkWidget::focus_padding = 0
|
||||
GtkOptionMenu::indicator_size = { 7, 13 }
|
||||
GtkOptionMenu::indicator_spacing = { 7, 5, 2, 2 }
|
||||
|
||||
Properties
|
||||
|
||||
GtkContainer::border_width = 0
|
||||
|
||||
#defines
|
||||
|
||||
CHILD_LEFT_SPACING = 5
|
||||
CHILD_RIGHT_SPACING = 1
|
||||
CHILD_TOP_SPACING = 1
|
||||
CHILD_BOTTOM_SPACING = 1
|
||||
|
||||
|
||||
I) interior_focus = TRUE
|
||||
|
||||
+--------------------------------------------------+
|
||||
+ A |
|
||||
| +----------------------------------------------+ |
|
||||
| |\\\\\\\\\\\\\\\\\\\\ H ///////////////////////| |
|
||||
| |\+------------------------------------------+/| |
|
||||
| |\| C |/| |
|
||||
| |\| +------------------------------+ |/| |
|
||||
| |\| |################ D ###########| L |/| |
|
||||
| |\| |#+--------------------------+#| |/| |
|
||||
| |\| |#| K |#| |/| |
|
||||
| |\| |#| +----------------------+ |#| +-----+ |/| |
|
||||
| |\| |#| | | |#| | /#\ | |/| |
|
||||
| |\| |#| | | |#| | === | |/| |
|
||||
|A|B|C|D|E| Child |F|D|G| IxJ |O|B|A|
|
||||
| |/| |#| | | |#| | === | |\| |
|
||||
| |/| |#| | | |#| | \#/ | |\| |
|
||||
| |/| |#| +----------------------+ |#| +-----+ |\| |
|
||||
| |/| |#| M |#| |\| |
|
||||
| |/| |#+---------------------------#| |\| |
|
||||
| |/| |################ D ###########| N |\| |
|
||||
| |/| +------------------------------+ |\| |
|
||||
| |/| C |\| |
|
||||
| |/+------------------------------------------+\| |
|
||||
| |//////////////////// H \\\\\\\\\\\\\\\\\\\\\\\| |
|
||||
| +----------------------------------------------+ |
|
||||
| A |
|
||||
+--------------------------------------------------+
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: xthickness
|
||||
C: GtkWidget::focus_pad
|
||||
D: GtkWidget::focus_width
|
||||
E: CHILD_LEFT_SPACING
|
||||
F: CHILD_RIGHT_SPACING
|
||||
G: GtkOptionMenu::indicator_spacing::left
|
||||
H: ythickness
|
||||
I: GtkOptionMenu::indicator_size::width
|
||||
J: GtkOptionMenu::indicator_size::height
|
||||
K: CHILD_TOP_SPACING
|
||||
L: GtkOptionMenu::indicator_spacing::top + GtkWidget::focus_width + GtkWidget::focus_pad + CHILD_TOP_SPACING
|
||||
M: CHILD_BOTTOM_SPACING
|
||||
N: GtkOptionMenu::indicator_spacing::bottom + GtkWidget::focus_width + GtkWidget::focus_pad + CHILD_BOTTOM_SPACING
|
||||
O: GtkOptionMenu::indicator_spacing::right
|
||||
|
||||
|
||||
II) interior_focus = FALSE
|
||||
|
||||
+--------------------------------------------------+
|
||||
+ A |
|
||||
| +----------------------------------------------+ |
|
||||
| |#################### B #######################| |
|
||||
| |#+------------------------------------------+#| |
|
||||
| |#| C |#| |
|
||||
| |#| +--------------------------------------+ |#| |
|
||||
| |#| |\\\\\\\\\\\\\\\\ H ///////////////////| |#| |
|
||||
| |#| |\+----------------------------------+/| |#| |
|
||||
| |#| |\| K L |/| |#| |
|
||||
| |#| |\| +----------------------+ +-----+ |/| |#| |
|
||||
| |#| |\| | | | /#\ | |/| |#| |
|
||||
| |#| |\| | | | === | |/| |#| |
|
||||
|A|B|C|D|E| Child |F| IxJ |G|D|C|B|A|
|
||||
| |#| |/| | | | === | |\| |#| |
|
||||
| |#| |/| | | | \#/ | |\| |#| |
|
||||
| |#| |/| +----------------------+ +-----+ |\| |#| |
|
||||
| |#| |/| M N |\| |#| |
|
||||
| |#| |/+----------------------------------+\| |#| |
|
||||
| |#| |//////////////// H \\\\\\\\\\\\\\\\\\\| |#| |
|
||||
| |#| +--------------------------------------+ |#| |
|
||||
| |#| C |#| |
|
||||
| |#+------------------------------------------+#| |
|
||||
| |#################### B #######################| |
|
||||
| +----------------------------------------------+ |
|
||||
| A |
|
||||
+--------------------------------------------------+
|
||||
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: GtkWidget::focus_width
|
||||
C: GtkWidget::focus_padding
|
||||
D: xthickness
|
||||
E: CHILD_LEFT_SPACING
|
||||
F: CHILD_RIGHT_SPACING + GtkOptionMenu::indicator_spacing::left
|
||||
G: GtkOptionMenu::indicator_spacing::right
|
||||
H: ythickness
|
||||
I: GtkOptionMenu::indicator_size::width
|
||||
J: GtkOptionMenu::indicator_size::height
|
||||
K: CHILD_TOP_SPACING
|
||||
L: CHILD_TOP_SPACING + GtkOptionMenu::indicator_spacing::top
|
||||
M: CHILD_BOTTOM_SPACING
|
||||
N: CHILD_BOTTOM_SPACING + GtkOptionMenu::indicator_spacing::bottom
|
||||
|
||||
|
||||
III) interior_focus = FALSE, !HAVE_FOCUS
|
||||
|
||||
+--------------------------------------------------+
|
||||
+ A |
|
||||
| +----------------------------------------------+ |
|
||||
| |\\\\\\\\\\\\\\\\\\\\ H ///////////////////////| |
|
||||
| |\+------------------------------------------+/| |
|
||||
| |\| |/| |
|
||||
| |\| |/| |
|
||||
| |\| |/| |
|
||||
| |\| |/| |
|
||||
| |\| K L |/| |
|
||||
| |\| +----------------------+ +-----+ |/| |
|
||||
| |\| | | | /#\ | |/| |
|
||||
| |\| | | | === | |/| |
|
||||
|A|D| E| Child |F| IxJ |G |D|A|
|
||||
| |/| | | | === | |\| |
|
||||
| |/| | | | \#/ | |\| |
|
||||
| |/| +----------------------+ +-----+ |\| |
|
||||
| |/| M N |\| |
|
||||
| |/| |\| |
|
||||
| |/| |\| |
|
||||
| |/| |\| |
|
||||
| |/| |\| |
|
||||
| |/+------------------------------------------+\| |
|
||||
| |//////////////////// H \\\\\\\\\\\\\\\\\\\\\\\| |
|
||||
| +----------------------------------------------+ |
|
||||
| A |
|
||||
+--------------------------------------------------+
|
||||
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: GtkWidget::focus_width
|
||||
C: GtkWidget::focus_padding
|
||||
D: xthickness
|
||||
E: CHILD_LEFT_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding
|
||||
F: CHILD_RIGHT_SPACING + GtkOptionMenu::in+icator_spacing::left
|
||||
G: GtkOptionMenu::indicator_spacing::right + GtkWidget::focus_width + GtkWidget::focus_padding
|
||||
H: ythickness
|
||||
I: GtkOptionMenu::indicator_size::width
|
||||
J: GtkOptionMenu::indicator_size::height
|
||||
K: CHILD_TOP_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding
|
||||
L: CHILD_TOP_SPACING + GtkOptionMenu::indicator_spacing::top + GtkWidget::focus_width + GtkWidget::focus_padding
|
||||
M: CHILD_BOTTOM_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding
|
||||
N: CHILD_BOTTOM_SPACING + GtkOptionMenu::indicator_spacing::bottom + GtkWidget::focus_width + GtkWidget::focus_padding
|
||||
|
||||
|
||||
|
||||
=====================
|
||||
|
||||
GtkButton
|
||||
|
||||
=====================
|
||||
|
||||
NOTE: Due to a bug that is basically unfixable in a sufficiently compatible
|
||||
NOTE: way, the button gives the space requested for focus_width and
|
||||
NOTE: focus_padding to the child (in addition to the space requested by
|
||||
NOTE: the child), if the button is !CAN_FOCUS.
|
||||
|
||||
Style properties
|
||||
|
||||
GtkWidget::interior_focus = TRUE
|
||||
GtkWidget::focus_width = 1
|
||||
GtkWidget::focus_padding = 0
|
||||
GtkButton::default_border = { 1, 1, 1, 1 };
|
||||
GtkButton::default_outside_border = { 0, 0, 0, 0 };
|
||||
GtkButton::child_displacement_x = 0;
|
||||
GtkButton::child_displacement_y = 0;
|
||||
|
||||
Properties
|
||||
|
||||
GtkContainer::border_width = 0
|
||||
|
||||
#defines
|
||||
|
||||
CHILD_SPACING 1
|
||||
|
||||
I) HAS_DEFAULT && (!GtkWidget::interior-focus || !HAVE_FOCUS)
|
||||
|
||||
+----------------------------------------------+
|
||||
| A |
|
||||
| +------------------------------------------+ |
|
||||
| |@@@@@@@@@@@@@@@@@@@ I @@@@@@@@@@@@@@@@@@@@| |
|
||||
| |@+--------------------------------------+@| |
|
||||
| |@|\\\\\\\\\\\\\\\\\ J //////////////////|@| |
|
||||
| |@|\+----------------------------------+/|@| |
|
||||
| |@|\| E |/|@| |
|
||||
| |@|\| +------------------------------+ |/|@| |
|
||||
| |@|\| |############# F ##############| |/|@| |
|
||||
| |@|\| |#+--------------------------+#| |/|@| |
|
||||
| |@|\| |#| L |#| |/|@| |
|
||||
| |@|\| |#| +----------------------+ |#| |/|@| |
|
||||
| |@|\| |#| | | |#| |/|@| |
|
||||
| |@|\| |#| | | |#| |/|@| |
|
||||
|A|B|D|E|F|G| Child |M|F|E|D|C|A|
|
||||
| |@|/| |#| | | |#| |\|@| |
|
||||
| |@|/| |#| | | |#| |\|@| |
|
||||
| |@|/| |#| +----------------------+ |#| |\|@| |
|
||||
| |@|/| |#| N |#| |\|@| |
|
||||
| |@|/| |#+--------------------------+#| |\|@| |
|
||||
| |@|/| |############# F ##############| |\|@| |
|
||||
| |@|/| +------------------------------+ |\|@| |
|
||||
| |@|/| E |\|@| |
|
||||
| |@|/+----------------------------------+\|@| |
|
||||
| |@|///////////////// J \\\\\\\\\\\\\\\\\\|@| |
|
||||
| |@+--------------------------------------+@| |
|
||||
| |@@@@@@@@@@@@@@@@@@@ K @@@@@@@@@@@@@@@@@@@@| |
|
||||
| +------------------------------------------+ |
|
||||
| A |
|
||||
+----------------------------------------------+
|
||||
|
||||
A: GtkContainer::border-width
|
||||
B: GtkButton::default-border::left
|
||||
C: GtkButton::default-border::right
|
||||
D: xthickness
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkWidget::focus-line-width
|
||||
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
|
||||
I: GtkButton::default-border::top
|
||||
J: ythickness
|
||||
K: GtkButton::default-border::bottom
|
||||
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
|
||||
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
|
||||
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
|
||||
|
||||
|
||||
II) !HAS_DEFAULT && (!GtkWidget::interior-focus || !HAVE_FOCUS)
|
||||
|
||||
+----------------------------------------------+
|
||||
| |
|
||||
| I |
|
||||
| |
|
||||
| +--------------------------------------+ |
|
||||
| |\\\\\\\\\\\\\\\\\ J //////////////////| |
|
||||
| |\+----------------------------------+/| |
|
||||
| |\| E |/| |
|
||||
| |\| +------------------------------+ |/| |
|
||||
| |\| |############# F ##############| |/| |
|
||||
| |\| |#+--------------------------+#| |/| |
|
||||
| |\| |#| L |#| |/| |
|
||||
| |\| |#| +----------------------+ |#| |/| |
|
||||
| |\| |#| | | |#| |/| |
|
||||
| |\| |#| | | |#| |/| |
|
||||
| B |D|E|F|G| Child |M|F|E|D| C |
|
||||
| |/| |#| | | |#| |\| |
|
||||
| |/| |#| | | |#| |\| |
|
||||
| |/| |#| +----------------------+ |#| |\| |
|
||||
| |/| |#| N |#| |\| |
|
||||
| |/| |#+--------------------------+#| |\| |
|
||||
| |/| |############# F ##############| |\| |
|
||||
| |/| +------------------------------+ |\| |
|
||||
| |/| E |\| |
|
||||
| |/+----------------------------------+\| |
|
||||
| |///////////////// J \\\\\\\\\\\\\\\\\\| |
|
||||
| +--------------------------------------+ |
|
||||
| |
|
||||
| K |
|
||||
| |
|
||||
+----------------------------------------------+
|
||||
|
||||
|
||||
a) CAN_DEFAULT
|
||||
|
||||
B: GtkContainer::border-width + GtkButton::default-outside-border::left
|
||||
C: GtkContainer::border-width + GtkButton::default-outside-border::right
|
||||
D: xthickness
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkWidget::focus-line-width
|
||||
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::left
|
||||
I: GtkContainer::border-width + GtkButton::default-outside-border::top
|
||||
J: ythickness
|
||||
K: GtkContainer::border-width + GtkButton::default-outside-border::bottom
|
||||
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::top
|
||||
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::right
|
||||
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::bottom
|
||||
|
||||
|
||||
b) !CAN_DEFAULT
|
||||
|
||||
B: GtkContainer::border-width
|
||||
C: GtkContainer::border-width
|
||||
D: xthickness
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkWidget::focus-line-width
|
||||
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
|
||||
I: GtkContainer::border-width
|
||||
J: ythickness
|
||||
K: GtkContainer::border-width
|
||||
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
|
||||
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
|
||||
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
|
||||
|
||||
|
||||
|
||||
|
||||
III) HAS_DEFAULT && (GtkWidget::interior-focus && HAVE_FOCUS)
|
||||
|
||||
+----------------------------------------------+
|
||||
| A |
|
||||
| +------------------------------------------+ |
|
||||
| |@@@@@@@@@@@@@@@@@@@ I @@@@@@@@@@@@@@@@@@@@| |
|
||||
| |@+--------------------------------------+@| |
|
||||
| |@|################# F ##################|@| |
|
||||
| |@|#+----------------------------------+#|@| |
|
||||
| |@|#| E |#|@| |
|
||||
| |@|#| +------------------------------+ |#|@| |
|
||||
| |@|#| |\\\\\\\\\\\\\ J //////////////| |#|@| |
|
||||
| |@|#| |\+--------------------------+/| |#|@| |
|
||||
| |@|#| |\| L |/| |#|@| |
|
||||
| |@|#| |\| +----------------------+ |/| |#|@| |
|
||||
| |@|#| |\| | | |/| |#|@| |
|
||||
| |@|#| |\| | | |/| |#|@| |
|
||||
|A|B|F|E|D|G| Child |M|D|E|F|C|A|
|
||||
| |@|#| |/| | | |\| |#|@| |
|
||||
| |@|#| |/| | | |\| |#|@| |
|
||||
| |@|#| |/| +----------------------+ |\| |#|@| |
|
||||
| |@|#| |/| N |\| |#|@| |
|
||||
| |@|#| |/+--------------------------+\| |#|@| |
|
||||
| |@|#| |///////////// J \\\\\\\\\\\\\\| |#|@| |
|
||||
| |@|#| +------------------------------+ |#|@| |
|
||||
| |@|#| E |#|@| |
|
||||
| |@|#+----------------------------------+#|@| |
|
||||
| |@|################# F ##################|@| |
|
||||
| |@+--------------------------------------+@| |
|
||||
| |@@@@@@@@@@@@@@@@@@@ K @@@@@@@@@@@@@@@@@@@@| |
|
||||
| +------------------------------------------+ |
|
||||
| A |
|
||||
+----------------------------------------------+
|
||||
|
||||
A: GtkContainer::border-width
|
||||
B: GtkButton::default-border::left
|
||||
C: GtkButton::default-border::right
|
||||
D: xthickness
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkWidget::focus-line-width
|
||||
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
|
||||
I: GtkButton::default-border::top
|
||||
J: ythickness
|
||||
K: GtkButton::default-border::bottom
|
||||
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
|
||||
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
|
||||
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
|
||||
|
||||
|
||||
IV) !HAS_DEFAULT && (GtkWidget::interior-focus && HAVE_FOCUS)
|
||||
|
||||
+----------------------------------------------+
|
||||
| |
|
||||
| I |
|
||||
| |
|
||||
| +--------------------------------------+ |
|
||||
| |################# J ##################| |
|
||||
| |#+----------------------------------+#| |
|
||||
| |#| E |#| |
|
||||
| |#| +------------------------------+ |#| |
|
||||
| |#| |\\\\\\\\\\\\\ F //////////////| |#| |
|
||||
| |#| |\+--------------------------+/| |#| |
|
||||
| |#| |\| L |/| |#| |
|
||||
| |#| |\| +----------------------+ |/| |#| |
|
||||
| |#| |\| | | |/| |#| |
|
||||
| |#| |\| | | |/| |#| |
|
||||
| B |D|E|F|G| Child |M|F|E|D| C |
|
||||
| |#| |/| | | |\| |#| |
|
||||
| |#| |/| | | |\| |#| |
|
||||
| |#| |/| +----------------------+ |\| |#| |
|
||||
| |#| |/| N |\| |#| |
|
||||
| |#| |/+--------------------------+\| |#| |
|
||||
| |#| |///////////// F \\\\\\\\\\\\\\| |#| |
|
||||
| |#| +------------------------------+ |#| |
|
||||
| |#| E |#| |
|
||||
| |#+----------------------------------+#| |
|
||||
| |################# J ##################| |
|
||||
| +--------------------------------------+ |
|
||||
| |
|
||||
| K |
|
||||
| |
|
||||
+----------------------------------------------+
|
||||
|
||||
|
||||
a) CAN_DEFAULT
|
||||
|
||||
B: GtkContainer::border-width + GtkButton::default-outside-border::left
|
||||
C: GtkContainer::border-width + GtkButton::default-outside-border::right
|
||||
D: xthickness
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkWidget::focus-line-width
|
||||
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::left
|
||||
I: GtkContainer::border-width + GtkButton::default-outside-border::top
|
||||
J: ythickness
|
||||
K: GtkContainer::border-width + GtkButton::default-outside-border::bottom
|
||||
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::top
|
||||
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::right
|
||||
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) +
|
||||
(GtkButton::default-outside-border - GtkButton::default-outside-border)::bottom
|
||||
|
||||
|
||||
b) !CAN_DEFAULT
|
||||
|
||||
B: GtkContainer::border-width
|
||||
C: GtkContainer::border-width
|
||||
D: xthickness
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkWidget::focus-line-width
|
||||
G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0)
|
||||
I: GtkContainer::border-width
|
||||
J: ythickness
|
||||
K: GtkContainer::border-width
|
||||
L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0)
|
||||
M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0)
|
||||
N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0)
|
||||
|
||||
|
||||
======================
|
||||
|
||||
GtkCheckButton
|
||||
|
||||
======================
|
||||
|
||||
Note: This is the draw_indicator=TRUE case; draw_indicator=FALSE
|
||||
is like GtkButton)
|
||||
|
||||
Style properties
|
||||
|
||||
GtkWidget::interior_focus = TRUE
|
||||
GtkWidget::focus_width = 1
|
||||
GtkWidget::focus_padding = 0
|
||||
GtkButton::indicator-size = 13
|
||||
GtkButton::indicator-spacing = 2
|
||||
|
||||
Properties
|
||||
|
||||
GtkContainer::border_width = 0
|
||||
|
||||
#defines
|
||||
|
||||
CHILD_SPACING 1
|
||||
|
||||
interior_focus
|
||||
|
||||
+-------------------------------------------+
|
||||
| F |
|
||||
| G +------------------------+ |
|
||||
| |########### D ##########| |
|
||||
| +------------+ |#+--------------------+#| |
|
||||
| | | |#| E |#| |
|
||||
| | | |#| +----------------+ |#| |
|
||||
| | | |#| | | |#| |
|
||||
|A| BxB |C|D|E| Child |E|#|F|
|
||||
| | | |#| | | |#| |
|
||||
| | | |#| +----------------+ |#| |
|
||||
| | | |#| E |#| |
|
||||
| +------------+ |#+--------------------+#| |
|
||||
| |########### D ##########| |
|
||||
| G +------------------------+ |
|
||||
| F |
|
||||
+-------------------------------------------+
|
||||
|
||||
A: GtkContainer::border-width + GtkCheckButton::indicator-spacing
|
||||
B: GtkCheckButton::indicator-size
|
||||
C: 2 * GtkCheckButton::indicator-spacing
|
||||
D: GtkWidget::focus-line-width
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkContainer::border-width
|
||||
G: GtkConainer::border-width + GtkCheckButton::indicator-spacing
|
||||
|
||||
!interior_focus
|
||||
|
||||
+-------------------------------------------+
|
||||
| A |
|
||||
| +---------------------------------------+ |
|
||||
| |################ D ####################| |
|
||||
| |#+-----------------------------------+#| |
|
||||
| |#| G E |#| |
|
||||
| |#| +------------+ +---------------+ |#| |
|
||||
| |#| | | | | |#| |
|
||||
| |#| | | | | |#| |
|
||||
|A|D|F| BxB |C | Child |E|D|A|
|
||||
| |#| | | | | |#| |
|
||||
| |#| | | | | |#| |
|
||||
| |#| +------------+ +---------------+ |#| |
|
||||
| |#| G E |#| |
|
||||
| |#+-----------------------------------+#| |
|
||||
| |################ D ####################| |
|
||||
| +---------------------------------------+ |
|
||||
| A |
|
||||
+-------------------------------------------+
|
||||
|
||||
A: GtkContainer::border-width
|
||||
B: GtkCheckButton::indicator-size
|
||||
C: 2 * GtkCheckButton::indicator-spacing
|
||||
D: GtkWidget::focus-line-width
|
||||
E: GtkWidget::focus-padding
|
||||
F: GtkWidget::focus-padding + GtkCheckButton::indicator-spacing
|
||||
G: GtkWidget::focus-padding + GtkCheckButton::indicator-spacing
|
||||
|
||||
===============
|
||||
|
||||
GtkEntry
|
||||
|
||||
===============
|
||||
|
||||
Style properties
|
||||
|
||||
GtkWidget::interior_focus = TRUE
|
||||
GtkWidget::focus_width = 1
|
||||
GtkWidget::focus_padding = 0
|
||||
|
||||
Properties
|
||||
|
||||
GtkContainer::border_width = 0
|
||||
|
||||
#defines
|
||||
|
||||
INNER_BORDER 2
|
||||
|
||||
|
||||
|
||||
interior_focus
|
||||
|
||||
+--------------------------------------+
|
||||
|\\\\\\\\\\\\\\\\\ B //////////////////|
|
||||
|\+----------------------------------+/|
|
||||
|\| D |/|
|
||||
|\| +------------------------------+ |/|
|
||||
|\| | | |/|
|
||||
|\| | | |/|
|
||||
|A|D| |D|A|
|
||||
|\| | | |/|
|
||||
|\| | | |/|
|
||||
|\| +------------------------------+ |/|
|
||||
|\| D |/|
|
||||
|\+----------------------------------+/|
|
||||
|///////////////// B \\\\\\\\\\\\\\\\\/|
|
||||
+--------------------------------------+
|
||||
|
||||
A: xthickness
|
||||
B: ythickness
|
||||
D: INNER_BORDER
|
||||
|
||||
!interior_focus
|
||||
|
||||
+------------------------------------------+
|
||||
|####################C#####################|
|
||||
|#+--------------------------------------+#|
|
||||
|#|\\\\\\\\\\\\\\\\\ B //////////////////|#|
|
||||
|#|\+----------------------------------+/|#|
|
||||
|#|\| D |/|#|
|
||||
|#|\| +------------------------------+ |/|#|
|
||||
|#|\| | | |/|#|
|
||||
|#|\| | | |/|#|
|
||||
|C|A|D| |D|A|C|
|
||||
|#|\| | | |/|#|
|
||||
|#|\| | | |/|#|
|
||||
|#|\| +------------------------------+ |/|#|
|
||||
|#|\| D |/|#|
|
||||
|#|\+----------------------------------+/|#|
|
||||
|#|///////////////// B \\\\\\\\\\\\\\\\\/|#|
|
||||
|#+--------------------------------------+#|
|
||||
|####################C#####################|
|
||||
+------------------------------------------+
|
||||
|
||||
A: xthickness
|
||||
B: ythickness
|
||||
C: GtkWidget::focus-line-width
|
||||
D: INNER_BORDER + (HAVE_FOCUS ? 0 : GtkWidget::focus-line-width
|
||||
|
||||
Note - effect here for !interior_focus is that bevel moves in
|
||||
by focus-line-width when entry gains focus
|
||||
|
||||
===============
|
||||
|
||||
GtkExpander
|
||||
|
||||
===============
|
||||
|
||||
Style properties
|
||||
GtkWidget::focus_line_width
|
||||
GtkWidget::focus_padding
|
||||
GtkExpander::expander_size
|
||||
GtkExpander::expander_spacing
|
||||
|
||||
Properties
|
||||
GtkContainer::border_width
|
||||
GtkExpander::spacing
|
||||
|
||||
if (GTK_WIDGET_VISIBLE (bin->child) && interior_focus)
|
||||
|
||||
+-------------------------------------+
|
||||
| A |
|
||||
| +---------+-----------------------+ |
|
||||
| | C |##########E############| |
|
||||
| | +-----+ |#+-------------------+#| |
|
||||
| | | | |#| F |#| |
|
||||
| | | | |#| +---------------+ |#| |
|
||||
|A|C| BxB |C|E|F| label_widget |F|E|A|
|
||||
| | | | |#| +---------------+ |#| |
|
||||
| | | | |#| F |#| |
|
||||
| | +-----+ |#+-------------------+#| |
|
||||
| | C |##########E############| |
|
||||
| +---------+-----------------------+ |
|
||||
| | D | |
|
||||
| +---------------------------------+ |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
|A| bin->child |A|
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| +---------------------------------+ |
|
||||
| A |
|
||||
+-------------------------------------+
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: GtkExpander::expander_size
|
||||
C: GtkExpander::expander_spacing
|
||||
D: GtkExpander::spacing
|
||||
E: GtkWidget::focus_line_width
|
||||
F: GtkWidget::focus_padding
|
||||
|
||||
if (GTK_WIDGET_VISIBLE (bin->child) && !interior_focus)
|
||||
|
||||
+-------------------------------------------+
|
||||
| A |
|
||||
| +---------------------------------------+ |
|
||||
| |##################E####################| |
|
||||
| |#+-----------------------------------+#| |
|
||||
| |#| F |#| |
|
||||
| |#| +---------+---------------------+ |#| |
|
||||
| |#| | C | | |#| |
|
||||
| |#| | +-----+ | | |#| |
|
||||
|A|E|F|C| BxB |C| label_widget |F|E|A|
|
||||
| |#| | +-----+ | | |#| |
|
||||
| |#| | C | | |#| |
|
||||
| |#| +---------+---------------------+ |#| |
|
||||
| |#| F |#| |
|
||||
| |#+-----------------------------------+#| |
|
||||
| |##################E####################| |
|
||||
| +---------------------------------------+ |
|
||||
| | D | |
|
||||
| +---------------------------------------+ |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
|A| bin->child |A|
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| +---------------------------------------+ |
|
||||
| A |
|
||||
+-------------------------------------------+
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: GtkExpander::expander_size
|
||||
C: GtkExpander::expander_spacing
|
||||
D: GtkExpander::spacing
|
||||
E: GtkWidget::focus_line_width
|
||||
F: GtkWidget::focus_padding
|
||||
|
||||
if (!GTK_WIDGET_VISIBLE (bin->child) && interior_focus)
|
||||
|
||||
+-------------------------------------+
|
||||
| A |
|
||||
| +---------+-----------------------+ |
|
||||
| | C |##########E############| |
|
||||
| | +-----+ |#+-------------------+#| |
|
||||
| | | | |#| F |#| |
|
||||
| | | | |#| +---------------+ |#| |
|
||||
|A|C| BxB |C|E|F| label_widget |F|E|A|
|
||||
| | | | |#| +---------------+ |#| |
|
||||
| | | | |#| F |#| |
|
||||
| | +-----+ |#+-------------------+#| |
|
||||
| | C |##########E############| |
|
||||
| +---------+-----------------------+ |
|
||||
| A |
|
||||
+-------------------------------------+
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: GtkExpander::expander_size
|
||||
C: GtkExpander::expander_spacing
|
||||
E: GtkWidget::focus_line_width
|
||||
F: GtkWidget::focus_padding
|
||||
|
||||
if (!GTK_WIDGET_VISIBLE (bin->child) && !interior_focus)
|
||||
|
||||
+-------------------------------------------+
|
||||
| A |
|
||||
| +---------------------------------------+ |
|
||||
| |##################E####################| |
|
||||
| |#+-----------------------------------+#| |
|
||||
| |#| F |#| |
|
||||
| |#| +---------+---------------------+ |#| |
|
||||
| |#| | C | | |#| |
|
||||
| |#| | +-----+ | | |#| |
|
||||
|A|E|F|C| BxB |C| label_widget |F|E|A|
|
||||
| |#| | +-----+ | | |#| |
|
||||
| |#| | C | | |#| |
|
||||
| |#| +---------+---------------------+ |#| |
|
||||
| |#| F |#| |
|
||||
| |#+-----------------------------------+#| |
|
||||
| |##################E####################| |
|
||||
| +---------------------------------------+ |
|
||||
| A |
|
||||
+-------------------------------------------+
|
||||
|
||||
A: GtkContainer::border_width
|
||||
B: GtkExpander::expander_size
|
||||
C: GtkExpander::expander_spacing
|
||||
E: GtkWidget::focus_line_width
|
||||
F: GtkWidget::focus_padding
|
||||
@@ -1,500 +0,0 @@
|
||||
Notes about the inner workings of the widget system of GTK
|
||||
==========================================================
|
||||
|
||||
This file contains some notes as to how the widget system does
|
||||
and should work. It consists of three parts:
|
||||
|
||||
I) A description of the meaning of the various flags
|
||||
|
||||
II) A list of invariants about the states of the widgets.
|
||||
(Throughout this document, we refer to the states of the
|
||||
widgets by referring to the flags for GtkWidget)
|
||||
|
||||
III) Some notes about the ways that a widget changes states
|
||||
|
||||
IV) A list of responsibilities of various widget signals when
|
||||
the states change.
|
||||
|
||||
Any action necessary to maintain the invariants in II which is not
|
||||
explicitly mentioned in IV), is the responsibility of the core GTK
|
||||
code, which is roughly defined as:
|
||||
|
||||
gtkobject.c
|
||||
gtkwidget.c
|
||||
gtkcontainer.c
|
||||
gtkmain.c
|
||||
gtksignal.c
|
||||
|
||||
Section II is mostly of interest to those maintaining GTK, the
|
||||
other sections may also be interesting to people writing
|
||||
new widgets.
|
||||
|
||||
Main outline:
|
||||
- Owen Taylor <owt1@cornell.edu>
|
||||
1998/02/03
|
||||
|
||||
Flag descriptions:
|
||||
- Tim Janik <timj@gimp.org>
|
||||
1998/02/04
|
||||
|
||||
I. Flags
|
||||
--------
|
||||
|
||||
GtkObject:
|
||||
|
||||
GTK_DESTROYED:
|
||||
This flagged is set for a GtkObject right before its
|
||||
destruction code is executed. Its main use is the
|
||||
prevention of multiple destruction invocations.
|
||||
|
||||
GTK_FLOATING:
|
||||
This flag reflects the fact that the holder of the
|
||||
initial reference count is unknown. Refer to refcounting.txt
|
||||
for further details.
|
||||
|
||||
GTK_RESERVED_1:
|
||||
GTK_RESERVED_2:
|
||||
Reserved flags.
|
||||
|
||||
|
||||
GtkWidget, public flags:
|
||||
|
||||
GTK_TOPLEVEL:
|
||||
Widgets without a real parent, as there are GtkWindows and
|
||||
GtkMenus have this flag set throughout their lifetime.
|
||||
Toplevel widgets always contain their own GdkSurface.
|
||||
|
||||
GTK_NO_WINDOW:
|
||||
This flag is indicative for a widget that does not provide
|
||||
its own GdkSurface. Visible action (e.g. drawing) is performed
|
||||
on the parent's GdkSurface.
|
||||
|
||||
GTK_REALIZED:
|
||||
Set by gtk_widget_realize, unset by gtk_widget_unrealize.
|
||||
Relies on ((widget->parent && widget->parent->window)
|
||||
|| GTK_WIDGET_TOPLEVEL (widget));
|
||||
Means: widget has an associated GdkSurface (XWindow).
|
||||
|
||||
GTK_MAPPED:
|
||||
Set by gtk_widget_map, unset by gtk_widget_unmap.
|
||||
May only be set if GTK_WIDGET_REALIZED (widget).
|
||||
Means: gdk_surface_show() has been called on the widgets window(s).
|
||||
|
||||
GTK_VISIBLE:
|
||||
Set by gtk_widget_show.
|
||||
Implies that a widget will be flagged GTK_MAPPED as soon as its
|
||||
parent is mapped.
|
||||
!GTK_VISIBLE:
|
||||
Set by gtk_widget_hide.
|
||||
Implies that a widget is not onscreen, therefore !GTK_MAPPED.
|
||||
|
||||
GTK_CHILD_VISIBLE
|
||||
Set by gtk_widget_set_child_visible, and if FALSE indicates that
|
||||
the widget should not be mapped even if the parent is mapped
|
||||
and visible. Containers like GtkNotebook use this flag.
|
||||
A private flag, not a public flag, so if you need to check
|
||||
this flag, you should call gtk_widget_get_child_visible().
|
||||
(Should be very rarely necessary.)
|
||||
|
||||
GTK_SENSITIVE:
|
||||
Set and unset by gtk_widget_set_sensitive.
|
||||
The sensitivity of a widget determines whether it will receive
|
||||
certain events (e.g. button or key presses). One premise for
|
||||
the widgets sensitivity is to have GTK_SENSITIVE set.
|
||||
|
||||
GTK_PARENT_SENSITIVE:
|
||||
Set and unset by gtk_widget_set_sensitive operations on the
|
||||
parents of the widget.
|
||||
This is the second premise for the widgets sensitivity. Once
|
||||
it has GTK_SENSITIVE and GTK_PARENT_SENSITIVE set, its state is
|
||||
effectively sensitive. This is expressed (and can be examined) by
|
||||
the GTK_WIDGET_IS_SENSITIVE macro.
|
||||
|
||||
GTK_CAN_FOCUS:
|
||||
There are no directly corresponding functions for setting/unsetting
|
||||
this flag, but it can be affected by the GtkWidget::has_focus argument
|
||||
via gtk_widget_set_arg.
|
||||
This flag determines whether a widget is able to handle focus grabs.
|
||||
|
||||
GTK_HAS_FOCUS:
|
||||
This flag will be set by gtk_widget_grab_focus for widgets that also
|
||||
have GTK_CAN_FOCUS set. The flag will be unset once another widget
|
||||
grabs the focus.
|
||||
|
||||
GTK_CAN_DEFAULT:
|
||||
GTK_HAS_DEFAULT:
|
||||
These two flags are mostly equal in functionality to their *_FOCUS
|
||||
counterparts, but for the default widget.
|
||||
|
||||
GTK_HAS_GRAB:
|
||||
Set by gtk_grab_add, unset by gtk_grab_remove.
|
||||
Means: widget is in the grab_widgets stack, and will be the preferred
|
||||
one for receiving events other than ones of cosmetic value.
|
||||
|
||||
GTK_BASIC:
|
||||
The GTK_BASIC flag is an attempt at making a distinction
|
||||
between widgets that handle user input e.g. key/button presses
|
||||
and those that don't. Subsequent parent<->child relation ships
|
||||
of non `basic' widgets should be avoided. The checking for
|
||||
this is currently not properly enforced in the code. For
|
||||
example GtkButton is a non `basic' widget, that will therefore
|
||||
disallow to act as a container for another GtkButton. Now the
|
||||
gnit is, one can add a GtkHBox (which is a `basic' widget) to
|
||||
the first button, and put the second into the box.
|
||||
|
||||
GTK_RESERVED_3:
|
||||
|
||||
GTK_RC_STYLE:
|
||||
This flag indicates that its style has been looked up through
|
||||
the rc mechanism. It does not imply that the widget actually
|
||||
had a style defined through the rc mechanism.
|
||||
|
||||
|
||||
GtkWidget, private flags:
|
||||
|
||||
GTK_USER_STYLE:
|
||||
A widget is flagged to have a user style, once gtk_widget_set_style
|
||||
has been invoked for it. The use of this flag is to tell widgets
|
||||
which share a global user style from the ones which got a certain
|
||||
style assign from outside the toolkit.
|
||||
|
||||
GTK_RESIZE_PENDING:
|
||||
First, this is only valid for GtkContainers.
|
||||
[some of the code should move to gtkcontainer.c therefore]
|
||||
Relies on GTK_WIDGET_REALIZED(widget)
|
||||
[this is not really enforced throughout the code, but should
|
||||
be. it only requires a few checks for GTK_WIDGET_REALIZED and
|
||||
minor changes to gtk_widget_unrealize, we can then remove the check
|
||||
in gtk_widget_real_destroy]
|
||||
Means: there is an idle handler waiting for the container to
|
||||
resize it.
|
||||
|
||||
GTK_RESIZE_NEEDED:
|
||||
Relies on GTK_WIDGET_REALIZED(widget)
|
||||
[this is not really enforced throughout the code, but should
|
||||
be. once this is done special checking in gtk_widget_real_destroy
|
||||
can be avoided]
|
||||
Means: a widget has been added to the resize_widgets list of
|
||||
its _toplevel_ container (keep this in mind for GtkViewport).
|
||||
Remark: this flag is also used internally by gtkwindow.c during
|
||||
the evaluation of resizing worthy widgets.
|
||||
|
||||
GTK_LEAVE_PENDING:
|
||||
A widget is flagged as such if there is a leave_notify event
|
||||
pending for it. It will receive this event regardless of a grab
|
||||
through another widget or its current sensitivity.
|
||||
[this should be made relying on GTK_REALIZED]
|
||||
|
||||
GTK_HAS_SHAPE_MASK:
|
||||
Set by gtk_widget_shape_combine_mask if a widget got a shape mask
|
||||
assigned (making use of the X11 shaped window extension).
|
||||
|
||||
GTK_IN_REPARENT:
|
||||
During the act of reparentation widgets which are already
|
||||
realized and will be added to an already realized parent need
|
||||
to have this flag set to prevent natural unrealization on the
|
||||
process of getting unparented.
|
||||
|
||||
GTK_NEED_REQUEST:
|
||||
This flag is set if the widget doesn't have an up to date
|
||||
requisition. If this flag is set, we must actually emit ::size-request
|
||||
when gtk_widget_size_request() is called. Otherwise, we can
|
||||
simply widget->requisition. We keep track of this all the time
|
||||
however, widgets with this flag set are only added to the resize
|
||||
queue if they are viewable.
|
||||
|
||||
GTK_NEED_ALLOCATION:
|
||||
This flag is set if the widget doesn't have an up to date
|
||||
allocation. If this flag is set, we must actually emit ::size-allocate
|
||||
when gtk_widget_size_allocate() is called, even if the new allocation
|
||||
is the same as the current allocation.
|
||||
|
||||
Related Macros:
|
||||
|
||||
GTK_WIDGET_DRAWABLE:
|
||||
This macro examines whether a widget is flagged as GTK_WIDGET_VISIBLE
|
||||
and GTK_WIDGET_MAPPED.
|
||||
Means: it _makes sense_ to draw in a widgets window.
|
||||
|
||||
GTK_WIDGET_IS_SENSITIVE:
|
||||
This macro tells the real sensitivity state of a widget. It returns
|
||||
whether both the widget and all its parents are in sensitive state.
|
||||
|
||||
|
||||
II. Invariants:
|
||||
---------------
|
||||
|
||||
This section describes various constraints on the states of
|
||||
the widget:
|
||||
|
||||
In the following
|
||||
|
||||
A => B means if A is true, than B is true
|
||||
A <=> B means A is true, if and only if B is true
|
||||
(equivalent to A => B and A <= B)
|
||||
|
||||
|
||||
1) GTK_WIDGET_DESTROYED (widget) => !GTK_WIDGET_REALIZED (widget)
|
||||
=> !GTK_WIDGET_VISIBLE (widget)
|
||||
[ The latter is not currently in place, but it should be ]
|
||||
|
||||
2) GTK_WIDGET_MAPPED (widget) => GTK_WIDGET_REALIZED (widget)
|
||||
|
||||
3) if GTK_WIDGET_TOPLEVEL (widget):
|
||||
GTK_WIDGET_VISIBLE (widget) <=> GTK_WIDGET_MAPPED (widget)
|
||||
|
||||
4) if !GTK_WIDGET_TOPLEVEL (widget):
|
||||
widget->parent && GTK_WIDGET_REALIZED (widget->parent) <=>
|
||||
GTK_WIDGET_REALIZED (widget)
|
||||
|
||||
5) if !GTK_WIDGET_TOPLEVEL (widget):
|
||||
|
||||
GTK_WIDGET_MAPPED (widget) => GTK_WIDGET_VISIBLE (widget)
|
||||
=> GTK_WIDGET_CHILD_VISIBLE (widget)
|
||||
=> GTK_WIDGET_REALIZED (widget)
|
||||
|
||||
widget->parent && GTK_WIDGET_MAPPED (widget->parent) &&
|
||||
GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_CHILD_VISIBLE
|
||||
<=> GTK_WIDGET_MAPPED (widget)
|
||||
|
||||
Note:, the definition
|
||||
|
||||
[ GTK_WIDGET_DRAWABLE = GTK_WIDGET_VISIBLE && GTK_WIDGET_MAPPED
|
||||
is made in gtkwidget.h, but by 3) and 5),
|
||||
|
||||
GTK_WIDGET_MAPPED => GTK_WIDGET_VISIBLE
|
||||
]
|
||||
|
||||
6) GTK_REDRAW_PENDING => GTK_WIDGET_REALIZED
|
||||
GTK_RESIZE_PENDING => "
|
||||
GTK_LEAVE_PENDING => "
|
||||
GTK_RESIZE_NEEDED => "
|
||||
|
||||
III. How states are changed:
|
||||
----------------------------
|
||||
|
||||
How can the user control the state of a widget:
|
||||
-----------------------------------------------
|
||||
|
||||
(In the following, set flag means set the flag, do appropriate
|
||||
actions, and enforce above invariants)
|
||||
|
||||
gtk_widget_show:
|
||||
if !GTK_DESTROYED sets GTK_VISIBLE
|
||||
|
||||
gtk_widget_hide:
|
||||
if !GTK_VISIBLE for widget
|
||||
|
||||
gtk_widget_destroy:
|
||||
sets GTK_DESTROYED
|
||||
For a top-level widget
|
||||
|
||||
gtk_widget_realize:
|
||||
if !GTK_DESTROYED sets GTK_REALIZED
|
||||
- Calling gtk_widget_realize when the widget is not a descendant
|
||||
of a toplevel is an ERROR.
|
||||
|
||||
gtk_container_add (container, widget) [ and container-specific variants ]
|
||||
Sets widget->parent
|
||||
|
||||
gtk_container_remove (container, widget)
|
||||
unsets widget->parent
|
||||
|
||||
gtk_widget_reparent (widget, new_parent)
|
||||
Equivalent to removing widget from old parent and adding it to
|
||||
the new parent, except that the widget will not be temporarily
|
||||
unrealized if both the old parent and the new parent are realized.
|
||||
|
||||
|
||||
gtk_widget_unrealize
|
||||
gtk_widget_map
|
||||
gtk_widget_unmap
|
||||
|
||||
These functions are not meant to be used by applications - they
|
||||
are used only by GTK and widgets to enforce invariants on the
|
||||
state.
|
||||
|
||||
When The X window corresponding to a GTK window is destroyed:
|
||||
-------------------------------------------------------------
|
||||
|
||||
gtk_widget_destroy is called (as above).
|
||||
|
||||
|
||||
|
||||
IV. Responsibilities of widgets
|
||||
--------------------------------
|
||||
|
||||
Adding to a container
|
||||
---------------------
|
||||
|
||||
When a widget is added to a container, the container:
|
||||
|
||||
1) calls gtk_widget_set_parent_surface (widget, window) if
|
||||
the widget is being added to something other than container->window
|
||||
2) calls gtk_widget_set_parent (widget, container)
|
||||
|
||||
Removing from a container
|
||||
-------------------------
|
||||
|
||||
When a widget is removed to a container, the container:
|
||||
|
||||
1) Calls gtk_widget_unparent (widget)
|
||||
2) Queues a resize.
|
||||
|
||||
Notes:
|
||||
|
||||
gtk_widget_unparent unrealizes the widget except in the
|
||||
special case GTK_IN_REPARENT is set.
|
||||
|
||||
|
||||
At widget creation
|
||||
------------------
|
||||
|
||||
Widgets are created in an unrealized state.
|
||||
|
||||
1) The widget should allocate and initialize needed data structures
|
||||
|
||||
|
||||
The Realize signal
|
||||
------------------
|
||||
|
||||
When a widget receives the "realize" signal it should:
|
||||
|
||||
NO_WINDOW widgets: (probably OK to use default handler)
|
||||
|
||||
1) set the realized flag
|
||||
2) set widget->window
|
||||
widget->window = gtk_widget_get_parent_surface (widget);
|
||||
g_object_ref (widget->window);
|
||||
3) attach the widget's style
|
||||
|
||||
widget->style = gtk_style_attach (widget->style, widget->window);
|
||||
|
||||
widget with window(s)
|
||||
|
||||
1) set the REALIZED flag
|
||||
2) create windows with the parent obtained from
|
||||
gtk_widget_get_parent_surface (widget);
|
||||
3) attach the widget's style
|
||||
4) set the background color for the new window based on the style
|
||||
|
||||
The Map signal
|
||||
--------------
|
||||
|
||||
1) Set the MAPPED flag
|
||||
2) If the widget has any windows, gdk_surface_show those windows
|
||||
3) call gtk_widget_map for all child widgets that are
|
||||
VISIBLE, CHILD_VISIBLE and !MAPPED. (A widget will only
|
||||
be !CHILD_VISIBLE if the container set it that way, so
|
||||
most containers will not have to check this.)
|
||||
3) Do any other functions related to putting the widget onscreen.
|
||||
(for instance, showing extra popup windows...)
|
||||
|
||||
The Unmap signal
|
||||
----------------
|
||||
|
||||
When a widget receives the unmap signal, it must:
|
||||
|
||||
1) If the widget has a window, gdk_surface_hide that window,
|
||||
2) If the widget does not have a window, unmap all child widgets
|
||||
3) Do any other functions related to taking the widget offscreen
|
||||
(for instance, removing popup windows...)
|
||||
4) Unset GTK_MAPPED
|
||||
|
||||
|
||||
The Unrealize signal
|
||||
--------------------
|
||||
|
||||
When a widget receives the unrealize signal, it must
|
||||
|
||||
1) For any windows other than widget->window do:
|
||||
|
||||
gdk_surface_set_user_data (window, NULL);
|
||||
gdk_surface_destroy (window);
|
||||
|
||||
2) Call the parent's unrealize handler
|
||||
|
||||
|
||||
The Widget class unrealize handler will take care of unrealizing
|
||||
all children if necessary. [should this be made consistent with
|
||||
unmap???]
|
||||
|
||||
|
||||
The Destroy Signal
|
||||
------------------
|
||||
|
||||
Commentary:
|
||||
|
||||
The destroy signal probably shouldn't exist at all. A widget
|
||||
should merely be unrealized and removed from its parent
|
||||
when the user calls gtk_widget_destroy or a GDK_DESTROY event
|
||||
is received. However, a large body of code depends on
|
||||
getting a definitive signal when a widget goes away.
|
||||
|
||||
That could be put in the finalization step, but, especially
|
||||
with language bindings, the cleanup step may need to refer
|
||||
back to the widget. (To use gtk_widget_get_data, for instance)
|
||||
If it does so via a pointer in a closure (natural for
|
||||
Scheme, or Perl), then the finalization procedure will never
|
||||
be called.
|
||||
|
||||
Also, if we made that the finalization step, we would have
|
||||
to propagate the GDK_DESTROY event in any case, since it is
|
||||
at that point at which user-visible actions need to be taken.
|
||||
|
||||
|
||||
When a widget receives the destroy signal, it must:
|
||||
|
||||
1) If the widget "owns" any widgets other than its child
|
||||
widgets, (for instance popup windows) it should
|
||||
call gtk_widget_destroy () for them.
|
||||
|
||||
2) Call the parent class's destroy handler.
|
||||
|
||||
|
||||
The "destroy" signal will only be received once. A widget
|
||||
will never receive any other signals after the destroy
|
||||
signal (but see the section on "Finalize" below)
|
||||
|
||||
The widget must handle calls to all publically accessible
|
||||
functions in an innocuous manner even after a "destroy"
|
||||
signal. (A widget can assume that it will not be realized
|
||||
after a "destroy" signal is received, which may simplify
|
||||
handling this requirement)
|
||||
|
||||
|
||||
The Finalize Pseudo-signal
|
||||
--------------------------
|
||||
|
||||
The finalize pseudo-signal is received after all references
|
||||
to the widget have been removed. The finalize callback
|
||||
cannot make any GTK calls with the widget as a parameter.
|
||||
|
||||
1) Free any memory allocated by the widget. (But _not_
|
||||
the widget structure itself.
|
||||
|
||||
2) Call the parent class's finalize signal
|
||||
|
||||
|
||||
A note on chaining "destroy" signals and finalize signals:
|
||||
---------------------------------------------------------
|
||||
|
||||
This is done by code like:
|
||||
|
||||
if (GTK_OBJECT_CLASS (parent_class)->destroy)
|
||||
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
|
||||
|
||||
It may not be completely obvious why this works. Note
|
||||
that parent_class is a static variable on a per-class
|
||||
basis. So say: we have
|
||||
|
||||
GtkFoo <- GtkBar <- GtkWidget <-GtkObject
|
||||
|
||||
And that Foo, Widget, and Object all have destructors, but
|
||||
not Bar.
|
||||
|
||||
Then gtk_foo_destroy will call gtk_widget_destroy (because
|
||||
it was not overridden in the Bar class structure) and
|
||||
gtk_widget_destroy will call gtk_object_destroy because
|
||||
the parent_class variable referenced by gtk_foo_destroy is the
|
||||
static variable in gtkwidget.c: GtkObjectClass.
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdktextureprivate.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
@@ -222,3 +223,32 @@ gdk_pixbuf_get_from_surface (cairo_surface_t *surface,
|
||||
cairo_surface_destroy (surface);
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_pixbuf_get_from_texture:
|
||||
* @texture: a #GdkTexture
|
||||
*
|
||||
* Creates a new pixbuf from @texture. This should generally not be used
|
||||
* in newly written code as later stages will almost certainly convert
|
||||
* the pixbuf back into a texture to draw it on screen.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new #GdkPixbuf or %NULL
|
||||
* in case of an error
|
||||
*/
|
||||
GdkPixbuf *
|
||||
gdk_pixbuf_get_from_texture (GdkTexture *texture)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
int width, height;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
surface = gdk_texture_download_surface (texture);
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdktexture.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -42,6 +44,8 @@ GdkPixbuf *gdk_pixbuf_get_from_surface (cairo_surface_t *surface,
|
||||
gint src_y,
|
||||
gint width,
|
||||
gint height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkPixbuf *gdk_pixbuf_get_from_texture (GdkTexture *texture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -333,7 +333,6 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
* gdk_pixbuf_get_rowstride (pixbuf),
|
||||
g_object_unref,
|
||||
g_object_ref (pixbuf));
|
||||
|
||||
texture = gdk_memory_texture_new (gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf),
|
||||
gdk_pixbuf_get_has_alpha (pixbuf)
|
||||
|
||||
+73
-8
@@ -64,6 +64,9 @@ struct _GdkVulkanContextPrivate {
|
||||
guint n_images;
|
||||
VkImage *images;
|
||||
cairo_region_t **regions;
|
||||
|
||||
gboolean has_present_region;
|
||||
|
||||
#endif
|
||||
|
||||
guint32 draw_index;
|
||||
@@ -101,7 +104,7 @@ gdk_vulkan_strerror (VkResult result)
|
||||
* Becuse the Vulkan people don't make adding this too easy, here's
|
||||
* the process to manage it:
|
||||
* 1. go to
|
||||
* https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blame/master/include/vulkan/vulkan.h
|
||||
* https://github.com/KhronosGroup/Vulkan-Headers/blob/master/include/vulkan/vulkan_core.h
|
||||
* 2. Find the line where this enum value was added.
|
||||
* 3. Click the commit that added this line.
|
||||
* 4. The commit you're looking at now should also change
|
||||
@@ -198,6 +201,10 @@ gdk_vulkan_strerror (VkResult result)
|
||||
case VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
|
||||
return "Invalid device address";
|
||||
#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 exlusive full-screen access.";
|
||||
#endif
|
||||
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
@@ -385,6 +392,26 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
return res == VK_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_supports_incremental_present (VkPhysicalDevice device)
|
||||
{
|
||||
VkExtensionProperties *extensions;
|
||||
uint32_t n_device_extensions;
|
||||
|
||||
vkEnumerateDeviceExtensionProperties (device, NULL, &n_device_extensions, NULL);
|
||||
|
||||
extensions = g_newa (VkExtensionProperties, n_device_extensions);
|
||||
vkEnumerateDeviceExtensionProperties (device, NULL, &n_device_extensions, extensions);
|
||||
|
||||
for (uint32_t i = 0; i < n_device_extensions; i++)
|
||||
{
|
||||
if (g_str_equal (extensions[i].extensionName, VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
@@ -414,6 +441,29 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
|
||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||
VkPresentRegionsKHR *regionsptr = VK_NULL_HANDLE;
|
||||
VkPresentRegionsKHR regions;
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
cairo_region_get_extents (painted, &extents);
|
||||
|
||||
regions = (VkPresentRegionsKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR,
|
||||
.swapchainCount = 1,
|
||||
.pRegions = &(VkPresentRegionKHR) {
|
||||
.rectangleCount = 1,
|
||||
.pRectangles = &(VkRectLayerKHR) {
|
||||
.layer = 0,
|
||||
.offset.x = extents.x,
|
||||
.offset.y = extents.y,
|
||||
.extent.width = extents.width,
|
||||
.extent.height = extents.height,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (priv->has_present_region)
|
||||
regionsptr = ®ions;
|
||||
|
||||
GDK_VK_CHECK (vkQueuePresentKHR, gdk_vulkan_context_get_queue (context),
|
||||
&(VkPresentInfoKHR) {
|
||||
@@ -429,6 +479,7 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
|
||||
.pImageIndices = (uint32_t[]) {
|
||||
priv->draw_index
|
||||
},
|
||||
.pNext = regionsptr,
|
||||
});
|
||||
|
||||
cairo_region_destroy (priv->regions[priv->draw_index]);
|
||||
@@ -491,11 +542,12 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
||||
{
|
||||
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (initable);
|
||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
VkResult res;
|
||||
VkBool32 supported;
|
||||
uint32_t i;
|
||||
|
||||
priv->vulkan_ref = gdk_display_ref_vulkan (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), error);
|
||||
priv->vulkan_ref = gdk_display_ref_vulkan (display, error);
|
||||
if (!priv->vulkan_ref)
|
||||
return FALSE;
|
||||
|
||||
@@ -543,6 +595,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
||||
goto out_surface;
|
||||
}
|
||||
priv->image_format = formats[i];
|
||||
priv->has_present_region = device_supports_incremental_present (display->vk_physical_device);
|
||||
|
||||
if (!gdk_vulkan_context_check_swapchain (context, error))
|
||||
goto out_surface;
|
||||
@@ -866,11 +919,20 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, NULL);
|
||||
VkQueueFamilyProperties *queue_props = g_newa (VkQueueFamilyProperties, n_queue_props);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, queue_props);
|
||||
|
||||
for (j = 0; j < n_queue_props; j++)
|
||||
{
|
||||
if (queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
GPtrArray *device_extensions;
|
||||
gboolean has_incremental_present;
|
||||
|
||||
has_incremental_present = device_supports_incremental_present (devices[i]);
|
||||
|
||||
device_extensions = g_ptr_array_new ();
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
if (has_incremental_present)
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, VULKAN, g_print ("Using Vulkan device %u, queue %u\n", i, j));
|
||||
if (GDK_VK_CHECK (vkCreateDevice, devices[i],
|
||||
&(VkDeviceCreateInfo) {
|
||||
@@ -886,14 +948,17 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
},
|
||||
0,
|
||||
NULL,
|
||||
1,
|
||||
(const char * const []) {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
},
|
||||
device_extensions->len,
|
||||
(const gchar * const *) device_extensions->pdata
|
||||
},
|
||||
NULL,
|
||||
&display->vk_device) != VK_SUCCESS)
|
||||
continue;
|
||||
{
|
||||
g_ptr_array_unref (device_extensions);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_ptr_array_unref (device_extensions);
|
||||
|
||||
display->vk_physical_device = devices[i];
|
||||
vkGetDeviceQueue(display->vk_device, j, 0, &display->vk_queue);
|
||||
|
||||
@@ -241,7 +241,6 @@ struct _GdkWaylandSeat
|
||||
guint32 repeat_key;
|
||||
guint32 repeat_count;
|
||||
gint64 repeat_deadline;
|
||||
GSettings *keyboard_settings;
|
||||
uint32_t keyboard_time;
|
||||
uint32_t keyboard_key_serial;
|
||||
|
||||
@@ -2013,26 +2012,6 @@ keyboard_handle_leave (void *data,
|
||||
|
||||
static gboolean keyboard_repeat (gpointer data);
|
||||
|
||||
static GSettings *
|
||||
get_keyboard_settings (GdkWaylandSeat *seat)
|
||||
{
|
||||
if (!seat->keyboard_settings)
|
||||
{
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsSchema *schema;
|
||||
|
||||
source = g_settings_schema_source_get_default ();
|
||||
schema = g_settings_schema_source_lookup (source, "org.gnome.settings-daemon.peripherals.keyboard", FALSE);
|
||||
if (schema != NULL)
|
||||
{
|
||||
seat->keyboard_settings = g_settings_new_full (schema, NULL, NULL);
|
||||
g_settings_schema_unref (schema);
|
||||
}
|
||||
}
|
||||
|
||||
return seat->keyboard_settings;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_key_repeat (GdkWaylandSeat *seat,
|
||||
guint *delay,
|
||||
@@ -2055,20 +2034,9 @@ get_key_repeat (GdkWaylandSeat *seat,
|
||||
}
|
||||
else
|
||||
{
|
||||
GSettings *keyboard_settings = get_keyboard_settings (seat);
|
||||
|
||||
if (keyboard_settings)
|
||||
{
|
||||
repeat = g_settings_get_boolean (keyboard_settings, "repeat");
|
||||
*delay = g_settings_get_uint (keyboard_settings, "delay");
|
||||
*interval = g_settings_get_uint (keyboard_settings, "repeat-interval");
|
||||
}
|
||||
else
|
||||
{
|
||||
repeat = TRUE;
|
||||
*delay = 400;
|
||||
*interval = 80;
|
||||
}
|
||||
repeat = TRUE;
|
||||
*delay = 400;
|
||||
*interval = 80;
|
||||
}
|
||||
|
||||
return repeat;
|
||||
@@ -3327,6 +3295,8 @@ gdk_wayland_tablet_flush_frame_event (GdkWaylandTabletData *tablet,
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
g_object_ref (event);
|
||||
|
||||
switch ((guint) event->any.type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
@@ -3367,6 +3337,8 @@ gdk_wayland_tablet_flush_frame_event (GdkWaylandTabletData *tablet,
|
||||
emulate_crossing (event->any.surface, NULL,
|
||||
tablet->master, GDK_ENTER_NOTIFY,
|
||||
GDK_CROSSING_NORMAL, time);
|
||||
|
||||
g_object_unref (event);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -4490,7 +4462,7 @@ pointer_surface_enter (void *data,
|
||||
if (tablet)
|
||||
{
|
||||
tablet->pointer_info.pointer_surface_outputs =
|
||||
g_slist_append (seat->pointer_info.pointer_surface_outputs, output);
|
||||
g_slist_append (tablet->pointer_info.pointer_surface_outputs, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4519,7 +4491,7 @@ pointer_surface_leave (void *data,
|
||||
if (tablet)
|
||||
{
|
||||
tablet->pointer_info.pointer_surface_outputs =
|
||||
g_slist_remove (seat->pointer_info.pointer_surface_outputs, output);
|
||||
g_slist_remove (tablet->pointer_info.pointer_surface_outputs, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4563,7 +4535,6 @@ gdk_wayland_seat_finalize (GObject *object)
|
||||
g_object_unref (seat->keymap);
|
||||
gdk_wayland_pointer_data_finalize (&seat->pointer_info);
|
||||
/* FIXME: destroy data_device */
|
||||
g_clear_object (&seat->keyboard_settings);
|
||||
g_clear_object (&seat->drag);
|
||||
g_clear_object (&seat->drop);
|
||||
g_clear_object (&seat->clipboard);
|
||||
|
||||
@@ -416,8 +416,8 @@ gdk_registry_handle_global (void *data,
|
||||
if (strcmp (interface, "wl_compositor") == 0)
|
||||
{
|
||||
display_wayland->compositor =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_compositor_interface, MIN (version, 3));
|
||||
display_wayland->compositor_version = MIN (version, 3);
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_compositor_interface, MIN (version, 4));
|
||||
display_wayland->compositor_version = MIN (version, 4);
|
||||
}
|
||||
else if (strcmp (interface, "wl_shm") == 0)
|
||||
{
|
||||
@@ -2215,12 +2215,19 @@ should_update_monitor (GdkWaylandMonitor *monitor)
|
||||
monitor->version < OUTPUT_VERSION_WITH_DONE);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
static gboolean
|
||||
should_expect_xdg_output_done (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GdkDisplay *display = GDK_MONITOR (monitor)->display;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
return (monitor_has_xdg_output (monitor) &&
|
||||
display_wayland->xdg_output_manager_version < NO_XDG_OUTPUT_DONE_SINCE_VERSION);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("monitor %d changed position %d %d, size %d %d",
|
||||
monitor->id,
|
||||
@@ -2231,11 +2238,7 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
|
||||
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
|
||||
monitor->wl_output_done = FALSE;
|
||||
/* xdg_output v3 marks xdg_output.done as deprecated, so if using
|
||||
* that version, no need to wait for xdg-output.done event.
|
||||
*/
|
||||
monitor->xdg_output_done =
|
||||
(display_wayland->xdg_output_manager_version >= NO_XDG_OUTPUT_DONE_SINCE_VERSION);
|
||||
monitor->xdg_output_done = FALSE;
|
||||
|
||||
update_scale (GDK_MONITOR (monitor)->display);
|
||||
}
|
||||
@@ -2280,7 +2283,7 @@ xdg_output_handle_done (void *data,
|
||||
g_message ("handle done xdg-output %d", monitor->id));
|
||||
|
||||
monitor->xdg_output_done = TRUE;
|
||||
if (monitor->wl_output_done)
|
||||
if (monitor->wl_output_done && should_expect_xdg_output_done (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
@@ -2377,7 +2380,7 @@ output_handle_done (void *data,
|
||||
|
||||
monitor->wl_output_done = TRUE;
|
||||
|
||||
if (!monitor_has_xdg_output (monitor) || monitor->xdg_output_done)
|
||||
if (!should_expect_xdg_output_done (monitor) || monitor->xdg_output_done)
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
|
||||
@@ -4063,8 +4063,11 @@ xdg_exported_handle (void *data,
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
impl->exported.callback (surface, handle, impl->exported.user_data);
|
||||
g_clear_pointer (&impl->exported.user_data,
|
||||
impl->exported.destroy_func);
|
||||
if (impl->exported.destroy_func)
|
||||
{
|
||||
g_clear_pointer (&impl->exported.user_data,
|
||||
impl->exported.destroy_func);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct zxdg_exported_v1_listener xdg_exported_listener = {
|
||||
@@ -4181,8 +4184,11 @@ gdk_wayland_surface_unexport_handle (GdkSurface *surface)
|
||||
|
||||
g_clear_pointer (&impl->display_server.xdg_exported,
|
||||
zxdg_exported_v1_destroy);
|
||||
g_clear_pointer (&impl->exported.user_data,
|
||||
impl->exported.destroy_func);
|
||||
if (impl->exported.destroy_func)
|
||||
{
|
||||
g_clear_pointer (&impl->exported.user_data,
|
||||
impl->exported.destroy_func);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -44,7 +44,7 @@ struct _GdkX11SelectionOutputStreamPrivate {
|
||||
Atom xtarget;
|
||||
char *property;
|
||||
Atom xproperty;
|
||||
const char *type;
|
||||
char *type;
|
||||
Atom xtype;
|
||||
int format;
|
||||
gulong timestamp;
|
||||
@@ -564,6 +564,7 @@ gdk_x11_selection_output_stream_finalize (GObject *object)
|
||||
g_free (priv->selection);
|
||||
g_free (priv->target);
|
||||
g_free (priv->property);
|
||||
g_free (priv->type);
|
||||
|
||||
G_OBJECT_CLASS (gdk_x11_selection_output_stream_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
+6
-15
@@ -46,8 +46,8 @@ struct _GskGLDriver
|
||||
|
||||
Fbo default_fbo;
|
||||
|
||||
GHashTable *textures;
|
||||
GHashTable *pointer_textures;
|
||||
GHashTable *textures; /* texture_id -> Texture */
|
||||
GHashTable *pointer_textures; /* pointer -> texture_id */
|
||||
|
||||
const Texture *bound_source_texture;
|
||||
|
||||
@@ -554,21 +554,12 @@ gsk_gl_driver_get_texture_for_pointer (GskGLDriver *self,
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer value_p;
|
||||
/* Find the texture in self->textures and mark it used */
|
||||
Texture *t;
|
||||
|
||||
g_hash_table_iter_init (&iter, self->textures);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value_p))
|
||||
{
|
||||
Texture *t = value_p;
|
||||
t = g_hash_table_lookup (self->textures, GINT_TO_POINTER (id));
|
||||
|
||||
if (t->texture_id == id)
|
||||
{
|
||||
t->in_use = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t != NULL)
|
||||
t->in_use = TRUE;
|
||||
}
|
||||
|
||||
return id;
|
||||
|
||||
+113
-123
@@ -11,19 +11,24 @@
|
||||
#include <graphene.h>
|
||||
#include <cairo.h>
|
||||
#include <epoxy/gl.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Cache eviction strategy
|
||||
*
|
||||
* Each cached glyph has an age that gets reset every time a cached
|
||||
* glyph gets used. Glyphs that have not been used for the
|
||||
* MAX_FRAME_AGE frames are considered old.
|
||||
* We mark glyphs as accessed every time we use them.
|
||||
* Every few frames, we mark glyphs that haven't been
|
||||
* accessed since the last check as old.
|
||||
*
|
||||
* We keep count of the pixels of each atlas that are taken up by old
|
||||
* data. When the fraction of old pixels gets too high, we drop the
|
||||
* atlas and all the items it contained.
|
||||
* We keep count of the pixels of each atlas that are
|
||||
* taken up by old data. When the fraction of old pixels
|
||||
* gets too high, we drop the atlas and all the items it
|
||||
* contained.
|
||||
*
|
||||
* Big glyphs are not stored in the atlas, they get their
|
||||
* own texture, but they are still cached.
|
||||
*/
|
||||
|
||||
#define MAX_FRAME_AGE (5 * 60)
|
||||
#define MAX_FRAME_AGE (60)
|
||||
#define MAX_GLYPH_SIZE 128 /* Will get its own texture if bigger */
|
||||
|
||||
static guint glyph_cache_hash (gconstpointer v);
|
||||
@@ -78,14 +83,7 @@ gsk_gl_glyph_cache_unref (GskGLGlyphCache *self)
|
||||
static gboolean
|
||||
glyph_cache_equal (gconstpointer v1, gconstpointer v2)
|
||||
{
|
||||
const GlyphCacheKey *key1 = v1;
|
||||
const GlyphCacheKey *key2 = v2;
|
||||
|
||||
return key1->font == key2->font &&
|
||||
key1->glyph == key2->glyph &&
|
||||
key1->xshift == key2->xshift &&
|
||||
key1->yshift == key2->yshift &&
|
||||
key1->scale == key2->scale;
|
||||
return memcmp (v1, v2, sizeof (CacheKeyData)) == 0;
|
||||
}
|
||||
|
||||
static guint
|
||||
@@ -93,11 +91,7 @@ glyph_cache_hash (gconstpointer v)
|
||||
{
|
||||
const GlyphCacheKey *key = v;
|
||||
|
||||
return GPOINTER_TO_UINT (key->font) ^
|
||||
key->glyph ^
|
||||
(key->xshift << 24) ^
|
||||
(key->yshift << 26) ^
|
||||
key->scale;
|
||||
return key->hash;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -105,7 +99,7 @@ glyph_cache_key_free (gpointer v)
|
||||
{
|
||||
GlyphCacheKey *f = v;
|
||||
|
||||
g_object_unref (f->font);
|
||||
g_object_unref (f->data.font);
|
||||
g_free (f);
|
||||
}
|
||||
|
||||
@@ -129,31 +123,31 @@ render_glyph (GlyphCacheKey *key,
|
||||
int stride;
|
||||
unsigned char *data;
|
||||
|
||||
scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)key->font);
|
||||
scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)key->data.font);
|
||||
if (G_UNLIKELY (!scaled_font || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS))
|
||||
{
|
||||
g_warning ("Failed to get a font");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
surface_width = value->draw_width * key->scale / 1024;
|
||||
surface_height = value->draw_height * key->scale / 1024;
|
||||
surface_width = value->draw_width * key->data.scale / 1024;
|
||||
surface_height = value->draw_height * key->data.scale / 1024;
|
||||
|
||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, surface_width);
|
||||
data = g_malloc0 (stride * surface_height);
|
||||
surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
|
||||
surface_width, surface_height,
|
||||
stride);
|
||||
cairo_surface_set_device_scale (surface, key->scale / 1024.0, key->scale / 1024.0);
|
||||
cairo_surface_set_device_scale (surface, key->data.scale / 1024.0, key->data.scale / 1024.0);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_set_scaled_font (cr, scaled_font);
|
||||
cairo_set_source_rgba (cr, 1, 1, 1, 1);
|
||||
|
||||
glyph_info.glyph = key->glyph;
|
||||
glyph_info.glyph = key->data.glyph;
|
||||
glyph_info.geometry.width = value->draw_width * 1024;
|
||||
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
if (glyph_info.glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
glyph_info.geometry.x_offset = 0;
|
||||
else
|
||||
glyph_info.geometry.x_offset = - value->draw_x * 1024;
|
||||
@@ -162,7 +156,7 @@ render_glyph (GlyphCacheKey *key,
|
||||
glyph_string.num_glyphs = 1;
|
||||
glyph_string.glyphs = &glyph_info;
|
||||
|
||||
pango_cairo_show_glyph_string (cr, key->font, &glyph_string);
|
||||
pango_cairo_show_glyph_string (cr, key->data.font, &glyph_string);
|
||||
cairo_destroy (cr);
|
||||
|
||||
cairo_surface_flush (surface);
|
||||
@@ -195,15 +189,17 @@ upload_glyph (GlyphCacheKey *key,
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
"Uploading glyph %d",
|
||||
key->glyph);
|
||||
key->data.glyph);
|
||||
|
||||
if (render_glyph (key, value, &r))
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, r.stride / 4);
|
||||
glBindTexture (GL_TEXTURE_2D, value->texture_id);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
r.x, r.y, r.width, r.height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
r.data);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
g_free (r.data);
|
||||
}
|
||||
|
||||
@@ -216,8 +212,8 @@ add_to_cache (GskGLGlyphCache *self,
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *value)
|
||||
{
|
||||
const int width = value->draw_width * key->scale / 1024;
|
||||
const int height = value->draw_height * key->scale / 1024;
|
||||
const int width = value->draw_width * key->data.scale / 1024;
|
||||
const int height = value->draw_height * key->data.scale / 1024;
|
||||
|
||||
if (width < MAX_GLYPH_SIZE && height < MAX_GLYPH_SIZE)
|
||||
{
|
||||
@@ -240,6 +236,7 @@ add_to_cache (GskGLGlyphCache *self,
|
||||
{
|
||||
value->atlas = NULL;
|
||||
value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
|
||||
gsk_gl_driver_mark_texture_permanent (driver, value->texture_id);
|
||||
|
||||
gsk_gl_driver_bind_source_texture (driver, value->texture_id);
|
||||
gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_LINEAR, GL_LINEAR);
|
||||
@@ -253,99 +250,72 @@ add_to_cache (GskGLGlyphCache *self,
|
||||
upload_glyph (key, value);
|
||||
}
|
||||
|
||||
#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
|
||||
|
||||
gboolean
|
||||
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float x,
|
||||
float y,
|
||||
float scale,
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *cached_glyph_out)
|
||||
void
|
||||
gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *cache,
|
||||
GlyphCacheKey *lookup,
|
||||
GskGLDriver *driver,
|
||||
const GskGLCachedGlyph **cached_glyph_out)
|
||||
{
|
||||
GskGLCachedGlyph *value;
|
||||
guint xshift = PHASE (x);
|
||||
guint yshift = PHASE (y);
|
||||
const guint key_scale = (guint)(scale * 1024);
|
||||
|
||||
value = g_hash_table_lookup (cache->hash_table,
|
||||
&(GlyphCacheKey) {
|
||||
.font = font,
|
||||
.glyph = glyph,
|
||||
.xshift = xshift,
|
||||
.yshift = yshift,
|
||||
.scale = key_scale
|
||||
});
|
||||
value = g_hash_table_lookup (cache->hash_table, lookup);
|
||||
|
||||
if (value)
|
||||
{
|
||||
const guint age = cache->timestamp - value->timestamp;
|
||||
|
||||
if (age > MAX_FRAME_AGE)
|
||||
if (value->atlas && !value->used)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = value->atlas;
|
||||
|
||||
if (atlas && !value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_used (atlas, value->draw_width, value->draw_height);
|
||||
value->used = TRUE;
|
||||
}
|
||||
|
||||
value->timestamp = cache->timestamp;
|
||||
gsk_gl_texture_atlas_mark_used (value->atlas, value->draw_width, value->draw_height);
|
||||
value->used = TRUE;
|
||||
}
|
||||
value->accessed = TRUE;
|
||||
|
||||
value->timestamp = cache->timestamp;
|
||||
*cached_glyph_out = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
GlyphCacheKey *key;
|
||||
PangoRectangle ink_rect;
|
||||
{
|
||||
GlyphCacheKey *key;
|
||||
PangoRectangle ink_rect;
|
||||
|
||||
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
|
||||
pango_extents_to_pixels (&ink_rect, NULL);
|
||||
if (xshift != 0)
|
||||
ink_rect.width += 1;
|
||||
if (yshift != 0)
|
||||
ink_rect.height += 1;
|
||||
pango_font_get_glyph_extents (lookup->data.font, lookup->data.glyph, &ink_rect, NULL);
|
||||
pango_extents_to_pixels (&ink_rect, NULL);
|
||||
if (lookup->data.xshift != 0)
|
||||
ink_rect.width += 1;
|
||||
if (lookup->data.yshift != 0)
|
||||
ink_rect.height += 1;
|
||||
|
||||
value = g_new0 (GskGLCachedGlyph, 1);
|
||||
value = g_new0 (GskGLCachedGlyph, 1);
|
||||
|
||||
value->draw_x = ink_rect.x;
|
||||
value->draw_y = ink_rect.y;
|
||||
value->draw_width = ink_rect.width;
|
||||
value->draw_height = ink_rect.height;
|
||||
value->timestamp = cache->timestamp;
|
||||
value->atlas = NULL; /* For now */
|
||||
value->draw_x = ink_rect.x;
|
||||
value->draw_y = ink_rect.y;
|
||||
value->draw_width = ink_rect.width;
|
||||
value->draw_height = ink_rect.height;
|
||||
value->accessed = TRUE;
|
||||
value->atlas = NULL; /* For now */
|
||||
|
||||
key = g_new0 (GlyphCacheKey, 1);
|
||||
key = g_new0 (GlyphCacheKey, 1);
|
||||
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->xshift = xshift;
|
||||
key->yshift = yshift;
|
||||
key->scale = key_scale;
|
||||
key->data.font = g_object_ref (lookup->data.font);
|
||||
key->data.glyph = lookup->data.glyph;
|
||||
key->data.xshift = lookup->data.xshift;
|
||||
key->data.yshift = lookup->data.yshift;
|
||||
key->data.scale = lookup->data.scale;
|
||||
key->hash = lookup->hash;
|
||||
|
||||
if (key->scale > 0 &&
|
||||
value->draw_width * key->scale / 1024 > 0 &&
|
||||
value->draw_height * key->scale / 1024 > 0)
|
||||
add_to_cache (cache, key, driver, value);
|
||||
if (key->data.scale > 0 &&
|
||||
value->draw_width * key->data.scale / 1024 > 0 &&
|
||||
value->draw_height * key->data.scale / 1024 > 0)
|
||||
add_to_cache (cache, key, driver, value);
|
||||
|
||||
*cached_glyph_out = *value;
|
||||
g_hash_table_insert (cache->hash_table, key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
*cached_glyph_out = *value;
|
||||
}
|
||||
|
||||
return cached_glyph_out->atlas != NULL;
|
||||
*cached_glyph_out = value;
|
||||
g_hash_table_insert (cache->hash_table, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self)
|
||||
gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
|
||||
GskGLDriver *driver,
|
||||
GPtrArray *removed_atlases)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GlyphCacheKey *key;
|
||||
@@ -354,32 +324,52 @@ gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self)
|
||||
|
||||
self->timestamp++;
|
||||
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
|
||||
if (removed_atlases->len > 0)
|
||||
{
|
||||
guint pos;
|
||||
|
||||
if (!g_ptr_array_find (self->atlases->atlases, value->atlas, &pos))
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
|
||||
{
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
else
|
||||
{
|
||||
const guint age = self->timestamp - value->timestamp;
|
||||
|
||||
if (age > MAX_FRAME_AGE)
|
||||
if (g_ptr_array_find (removed_atlases, value->atlas, NULL))
|
||||
{
|
||||
GskGLTextureAtlas *atlas = value->atlas;
|
||||
|
||||
if (atlas && value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_unused (atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
}
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self->timestamp % MAX_FRAME_AGE == 30)
|
||||
{
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
|
||||
{
|
||||
if (!value->accessed)
|
||||
{
|
||||
if (value->atlas)
|
||||
{
|
||||
if (value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_unused (value->atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gl_driver_destroy_texture (driver, value->texture_id);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
|
||||
/* Sadly, if we drop an atlas-less cached glyph, we
|
||||
* have to treat it like a dropped atlas and purge
|
||||
* text node render data.
|
||||
*/
|
||||
dropped++;
|
||||
}
|
||||
}
|
||||
else
|
||||
value->accessed = FALSE;
|
||||
}
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, g_message ("%d glyphs cached", g_hash_table_size (self->hash_table)));
|
||||
}
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d glyphs", dropped));
|
||||
}
|
||||
|
||||
@@ -15,17 +15,45 @@ typedef struct
|
||||
GHashTable *hash_table;
|
||||
GskGLTextureAtlases *atlases;
|
||||
|
||||
guint64 timestamp;
|
||||
int timestamp;
|
||||
} GskGLGlyphCache;
|
||||
|
||||
typedef struct
|
||||
struct _CacheKeyData
|
||||
{
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
guint scale; /* times 1024 */
|
||||
} GlyphCacheKey;
|
||||
guint xshift : 3;
|
||||
guint yshift : 3;
|
||||
guint scale : 26; /* times 1024 */
|
||||
};
|
||||
|
||||
typedef struct _CacheKeyData CacheKeyData;
|
||||
|
||||
struct _GlyphCacheKey
|
||||
{
|
||||
CacheKeyData data;
|
||||
guint hash;
|
||||
};
|
||||
|
||||
typedef struct _GlyphCacheKey GlyphCacheKey;
|
||||
|
||||
#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
|
||||
|
||||
static inline void
|
||||
glyph_cache_key_set_glyph_and_shift (GlyphCacheKey *key,
|
||||
PangoGlyph glyph,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
key->data.glyph = glyph;
|
||||
key->data.xshift = PHASE (x);
|
||||
key->data.yshift = PHASE (y);
|
||||
key->hash = GPOINTER_TO_UINT (key->data.font) ^
|
||||
key->data.glyph ^
|
||||
(key->data.xshift << 24) ^
|
||||
(key->data.yshift << 26) ^
|
||||
key->data.scale;
|
||||
}
|
||||
|
||||
typedef struct _GskGLCachedGlyph GskGLCachedGlyph;
|
||||
|
||||
@@ -44,8 +72,8 @@ struct _GskGLCachedGlyph
|
||||
int draw_width;
|
||||
int draw_height;
|
||||
|
||||
guint64 timestamp;
|
||||
guint used: 1;
|
||||
guint accessed : 1; /* accessed since last check */
|
||||
guint used : 1; /* accounted as used in the atlas */
|
||||
};
|
||||
|
||||
|
||||
@@ -53,14 +81,12 @@ GskGLGlyphCache * gsk_gl_glyph_cache_new (GdkDisplay *display
|
||||
GskGLTextureAtlases *atlases);
|
||||
GskGLGlyphCache * gsk_gl_glyph_cache_ref (GskGLGlyphCache *self);
|
||||
void gsk_gl_glyph_cache_unref (GskGLGlyphCache *self);
|
||||
void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self);
|
||||
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float x,
|
||||
float y,
|
||||
float scale,
|
||||
void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
|
||||
GskGLDriver *driver,
|
||||
GskGLCachedGlyph *cached_glyph_out);
|
||||
GPtrArray *removed_atlases);
|
||||
void gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *self,
|
||||
GlyphCacheKey *lookup,
|
||||
GskGLDriver *driver,
|
||||
const GskGLCachedGlyph **cached_glyph_out);
|
||||
|
||||
#endif
|
||||
|
||||
+116
-101
@@ -5,16 +5,7 @@
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#define MAX_FRAME_AGE (5 * 60)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
graphene_rect_t texture_rect;
|
||||
GskGLTextureAtlas *atlas;
|
||||
int frame_age; /* Number of frames this icon is unused */
|
||||
guint used: 1;
|
||||
GdkTexture *source_texture;
|
||||
} IconData;
|
||||
#define MAX_FRAME_AGE 60
|
||||
|
||||
static void
|
||||
icon_data_free (gpointer p)
|
||||
@@ -64,156 +55,180 @@ gsk_gl_icon_cache_unref (GskGLIconCache *self)
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_icon_cache_begin_frame (GskGLIconCache *self)
|
||||
gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
|
||||
GPtrArray *removed_atlases)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GdkTexture *texture;
|
||||
IconData *icon_data;
|
||||
|
||||
/* Increase frame age of all icons */
|
||||
g_hash_table_iter_init (&iter, self->icons);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
|
||||
self->timestamp++;
|
||||
|
||||
/* Drop icons on removed atlases */
|
||||
if (removed_atlases->len > 0)
|
||||
{
|
||||
guint pos;
|
||||
guint dropped = 0;
|
||||
|
||||
if (!g_ptr_array_find (self->atlases->atlases, icon_data->atlas, &pos))
|
||||
g_hash_table_iter_init (&iter, self->icons);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
|
||||
{
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon_data->frame_age ++;
|
||||
|
||||
if (icon_data->frame_age > MAX_FRAME_AGE)
|
||||
if (g_ptr_array_find (removed_atlases, icon_data->atlas, NULL))
|
||||
{
|
||||
|
||||
if (icon_data->used)
|
||||
{
|
||||
const int w = icon_data->texture_rect.size.width * icon_data->atlas->width;
|
||||
const int h = icon_data->texture_rect.size.height * icon_data->atlas->height;
|
||||
|
||||
gsk_gl_texture_atlas_mark_unused (icon_data->atlas, w + 2, h + 2);
|
||||
icon_data->used = FALSE;
|
||||
}
|
||||
/* We do NOT remove the icon here. Instead, We wait until we drop the entire atlas.
|
||||
* This way we can revive it when we use it again. */
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
}
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d icons", dropped));
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: this could probably be done more efficiently */
|
||||
static cairo_surface_t *
|
||||
pad_surface (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_surface_t *padded;
|
||||
cairo_t *cr;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_matrix_t matrix;
|
||||
if (self->timestamp % MAX_FRAME_AGE == 0)
|
||||
{
|
||||
g_hash_table_iter_init (&iter, self->icons);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
|
||||
{
|
||||
if (!icon_data->accessed)
|
||||
{
|
||||
if (icon_data->used)
|
||||
{
|
||||
const int width = icon_data->source_texture->width;
|
||||
const int height = icon_data->source_texture->height;
|
||||
gsk_gl_texture_atlas_mark_unused (icon_data->atlas, width + 2, height + 2);
|
||||
icon_data->used = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
padded = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
cairo_image_surface_get_width (surface) + 2,
|
||||
cairo_image_surface_get_height (surface) + 2);
|
||||
icon_data->accessed = FALSE;
|
||||
}
|
||||
|
||||
cr = cairo_create (padded);
|
||||
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
|
||||
|
||||
cairo_matrix_init_translate (&matrix, -1, -1);
|
||||
cairo_pattern_set_matrix (pattern, &matrix);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
return padded;
|
||||
}
|
||||
|
||||
static void
|
||||
upload_region_or_else (GskGLIconCache *self,
|
||||
guint texture_id,
|
||||
GskImageRegion *region)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, region->x, region->y, region->width, region->height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, region->data);
|
||||
GSK_NOTE(GLYPH_CACHE, g_message ("%d icons cached", g_hash_table_size (self->icons)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
GdkTexture *texture,
|
||||
int *out_texture_id,
|
||||
graphene_rect_t *out_texture_rect)
|
||||
const IconData **out_icon_data)
|
||||
{
|
||||
IconData *icon_data = g_hash_table_lookup (self->icons, texture);
|
||||
|
||||
if (icon_data)
|
||||
{
|
||||
icon_data->frame_age = 0;
|
||||
if (!icon_data->used)
|
||||
{
|
||||
const int w = icon_data->texture_rect.size.width * icon_data->atlas->width;
|
||||
const int h = icon_data->texture_rect.size.height * icon_data->atlas->height;
|
||||
|
||||
gsk_gl_texture_atlas_mark_used (icon_data->atlas, w + 2, h + 2);
|
||||
gsk_gl_texture_atlas_mark_used (icon_data->atlas, texture->width + 2, texture->height + 2);
|
||||
icon_data->used = TRUE;
|
||||
}
|
||||
icon_data->accessed = TRUE;
|
||||
|
||||
*out_texture_id = icon_data->atlas->texture_id;
|
||||
*out_texture_rect = icon_data->texture_rect;
|
||||
*out_icon_data = icon_data;
|
||||
return;
|
||||
}
|
||||
|
||||
/* texture not on any atlas yet. Find a suitable one. */
|
||||
{
|
||||
const int width = gdk_texture_get_width (texture);
|
||||
const int height = gdk_texture_get_height (texture);
|
||||
const int width = texture->width;
|
||||
const int height = texture->height;
|
||||
GskGLTextureAtlas *atlas = NULL;
|
||||
int packed_x = 0;
|
||||
int packed_y = 0;
|
||||
GskImageRegion region;
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *padded_surface;
|
||||
unsigned char *surface_data;
|
||||
|
||||
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
|
||||
|
||||
icon_data = g_new0 (IconData, 1);
|
||||
icon_data->atlas = atlas;
|
||||
icon_data->frame_age = 0;
|
||||
icon_data->accessed = TRUE;
|
||||
icon_data->used = TRUE;
|
||||
icon_data->texture_id = atlas->texture_id;
|
||||
icon_data->source_texture = g_object_ref (texture);
|
||||
graphene_rect_init (&icon_data->texture_rect,
|
||||
(float)(packed_x + 1) / atlas->width,
|
||||
(float)(packed_y + 1) / atlas->height,
|
||||
(float)width / atlas->width,
|
||||
(float)height / atlas->height);
|
||||
icon_data->x = (float)(packed_x + 1) / atlas->width;
|
||||
icon_data->y = (float)(packed_y + 1) / atlas->width;
|
||||
icon_data->x2 = icon_data->x + (float)width / atlas->width;
|
||||
icon_data->y2 = icon_data->y + (float)height / atlas->height;
|
||||
|
||||
g_hash_table_insert (self->icons, texture, icon_data);
|
||||
|
||||
/* actually upload the texture */
|
||||
surface = gdk_texture_download_surface (texture);
|
||||
padded_surface = pad_surface (surface);
|
||||
region.x = packed_x;
|
||||
region.y = packed_y;
|
||||
region.width = width + 2;
|
||||
region.height = height + 2;
|
||||
region.data = cairo_image_surface_get_data (padded_surface);
|
||||
|
||||
surface_data = cairo_image_surface_get_data (surface);
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
"Uploading texture");
|
||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||
|
||||
upload_region_or_else (self, atlas->texture_id, ®ion);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1, packed_y + 1,
|
||||
width, height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
/* Padding top */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1, packed_y,
|
||||
width, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
/* Padding left */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y + 1,
|
||||
1, height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
/* Padding top left */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
|
||||
/* Padding right */
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + width + 1, packed_y + 1,
|
||||
1, height,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
/* Padding top right */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + width + 1, packed_y,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
/* Padding bottom */
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, height - 1);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1, packed_y + 1 + height,
|
||||
width, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
/* Padding bottom left */
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y + 1 + height,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
/* Padding bottom right */
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + 1 + width, packed_y + 1 + height,
|
||||
1, 1,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
surface_data);
|
||||
|
||||
/* Reset this */
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
|
||||
|
||||
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
|
||||
|
||||
*out_texture_id = atlas->texture_id;
|
||||
*out_texture_rect = icon_data->texture_rect;
|
||||
*out_icon_data = icon_data;
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
cairo_surface_destroy (padded_surface);
|
||||
|
||||
#if 0
|
||||
{
|
||||
|
||||
@@ -18,16 +18,27 @@ typedef struct
|
||||
GskGLTextureAtlases *atlases;
|
||||
GHashTable *icons; /* GdkTexture -> IconData */
|
||||
|
||||
int timestamp;
|
||||
} GskGLIconCache;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y, x2, y2;
|
||||
GskGLTextureAtlas *atlas;
|
||||
guint used : 1;
|
||||
guint accessed : 1;
|
||||
int texture_id;
|
||||
GdkTexture *source_texture;
|
||||
} IconData;
|
||||
|
||||
GskGLIconCache * gsk_gl_icon_cache_new (GdkDisplay *display,
|
||||
GskGLTextureAtlases *atlases);
|
||||
GskGLIconCache * gsk_gl_icon_cache_ref (GskGLIconCache *self);
|
||||
void gsk_gl_icon_cache_unref (GskGLIconCache *self);
|
||||
void gsk_gl_icon_cache_begin_frame (GskGLIconCache *self);
|
||||
void gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
|
||||
GPtrArray *removed_atlases);
|
||||
void gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
GdkTexture *texture,
|
||||
int *out_texture_id,
|
||||
graphene_rect_t *out_texture_rect);
|
||||
const IconData **out_icon_data);
|
||||
|
||||
#endif
|
||||
|
||||
+444
-558
File diff suppressed because it is too large
Load Diff
+117
-216
@@ -28,7 +28,6 @@ ops_finish (RenderOpBuilder *builder)
|
||||
g_array_free (builder->clip_stack, TRUE);
|
||||
builder->clip_stack = NULL;
|
||||
|
||||
builder->buffer_size = 0;
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
builder->current_modelview = NULL;
|
||||
@@ -57,36 +56,29 @@ ops_dump_framebuffer (RenderOpBuilder *builder,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
RenderOp op;
|
||||
OpDumpFrameBuffer *op;
|
||||
|
||||
op.op = OP_DUMP_FRAMEBUFFER;
|
||||
op.dump.filename = g_strdup (filename);
|
||||
op.dump.width = width;
|
||||
op.dump.height = height;
|
||||
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_DUMP_FRAMEBUFFER);
|
||||
op->filename = g_strdup (filename);
|
||||
op->width = width;
|
||||
op->height = height;
|
||||
}
|
||||
|
||||
void
|
||||
ops_push_debug_group (RenderOpBuilder *builder,
|
||||
const char *text)
|
||||
{
|
||||
RenderOp op;
|
||||
OpDebugGroup *op;
|
||||
|
||||
op.op = OP_PUSH_DEBUG_GROUP;
|
||||
strncpy (op.debug_group.text, text, sizeof(op.debug_group.text) - 1);
|
||||
op.debug_group.text[sizeof(op.debug_group.text) - 1] = 0; /* Ensure zero terminated */
|
||||
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_PUSH_DEBUG_GROUP);
|
||||
strncpy (op->text, text, sizeof(op->text) - 1);
|
||||
op->text[sizeof(op->text) - 1] = 0; /* Ensure zero terminated */
|
||||
}
|
||||
|
||||
void
|
||||
ops_pop_debug_group (RenderOpBuilder *builder)
|
||||
{
|
||||
RenderOp op;
|
||||
|
||||
op.op = OP_POP_DEBUG_GROUP;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
ops_begin (builder, OP_POP_DEBUG_GROUP);
|
||||
}
|
||||
|
||||
float
|
||||
@@ -189,6 +181,9 @@ ops_init (RenderOpBuilder *builder)
|
||||
|
||||
builder->current_opacity = 1.0f;
|
||||
|
||||
op_buffer_init (&builder->render_ops);
|
||||
builder->vertices = g_array_new (FALSE, TRUE, sizeof (GskQuadVertex));
|
||||
|
||||
for (i = 0; i < GL_N_PROGRAMS; i ++)
|
||||
{
|
||||
builder->program_state[i].opacity = 1.0f;
|
||||
@@ -204,6 +199,9 @@ ops_free (RenderOpBuilder *builder)
|
||||
{
|
||||
gsk_transform_unref (builder->program_state[i].modelview);
|
||||
}
|
||||
|
||||
g_array_unref (builder->vertices);
|
||||
op_buffer_destroy (&builder->render_ops);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -215,15 +213,15 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
static const GskRoundedRect empty_clip;
|
||||
static const graphene_matrix_t empty_matrix;
|
||||
static const graphene_rect_t empty_rect;
|
||||
RenderOp op;
|
||||
OpProgram *op;
|
||||
ProgramState *program_state;
|
||||
|
||||
if (builder->current_program == program)
|
||||
return;
|
||||
|
||||
op.op = OP_CHANGE_PROGRAM;
|
||||
op.program = program;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_CHANGE_PROGRAM);
|
||||
op->program = program;
|
||||
|
||||
builder->current_program = program;
|
||||
|
||||
program_state = &builder->program_state[program->index];
|
||||
@@ -232,18 +230,20 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
if (memcmp (&empty_matrix, &program_state->projection, sizeof (graphene_matrix_t)) == 0 ||
|
||||
memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
|
||||
{
|
||||
op.op = OP_CHANGE_PROJECTION;
|
||||
op.projection = builder->current_projection;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
OpMatrix *opm;
|
||||
|
||||
opm = ops_begin (builder, OP_CHANGE_PROJECTION);
|
||||
opm->matrix = builder->current_projection;
|
||||
program_state->projection = builder->current_projection;
|
||||
}
|
||||
|
||||
if (program_state->modelview == NULL ||
|
||||
!gsk_transform_equal (builder->current_modelview, program_state->modelview))
|
||||
{
|
||||
op.op = OP_CHANGE_MODELVIEW;
|
||||
gsk_transform_to_matrix (builder->current_modelview, &op.modelview);
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
OpMatrix *opm;
|
||||
|
||||
opm = ops_begin (builder, OP_CHANGE_MODELVIEW);
|
||||
gsk_transform_to_matrix (builder->current_modelview, &opm->matrix);
|
||||
gsk_transform_unref (program_state->modelview);
|
||||
program_state->modelview = gsk_transform_ref (builder->current_modelview);
|
||||
}
|
||||
@@ -251,26 +251,29 @@ ops_set_program (RenderOpBuilder *builder,
|
||||
if (rect_equal (&empty_rect, &program_state->viewport) ||
|
||||
!rect_equal (&builder->current_viewport, &program_state->viewport))
|
||||
{
|
||||
op.op = OP_CHANGE_VIEWPORT;
|
||||
op.viewport = builder->current_viewport;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
OpViewport *opv;
|
||||
|
||||
opv = ops_begin (builder, OP_CHANGE_VIEWPORT);
|
||||
opv->viewport = builder->current_viewport;
|
||||
program_state->viewport = builder->current_viewport;
|
||||
}
|
||||
|
||||
if (memcmp (&empty_clip, &program_state->clip, sizeof (GskRoundedRect)) == 0 ||
|
||||
memcmp (&builder->current_clip, &program_state->clip, sizeof (GskRoundedRect)) != 0)
|
||||
{
|
||||
op.op = OP_CHANGE_CLIP;
|
||||
op.clip = *builder->current_clip;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
OpClip *opc;
|
||||
|
||||
opc = ops_begin (builder, OP_CHANGE_CLIP);
|
||||
opc->clip = *builder->current_clip;
|
||||
program_state->clip = *builder->current_clip;
|
||||
}
|
||||
|
||||
if (program_state->opacity != builder->current_opacity)
|
||||
{
|
||||
op.op = OP_CHANGE_OPACITY;
|
||||
op.opacity = builder->current_opacity;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
OpOpacity *opo;
|
||||
|
||||
opo = ops_begin (builder, OP_CHANGE_OPACITY);
|
||||
opo->opacity = builder->current_opacity;
|
||||
program_state->opacity = builder->current_opacity;
|
||||
}
|
||||
}
|
||||
@@ -279,30 +282,17 @@ static void
|
||||
ops_set_clip (RenderOpBuilder *builder,
|
||||
const GskRoundedRect *clip)
|
||||
{
|
||||
RenderOp *last_op;
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
OpClip *op;
|
||||
|
||||
if (current_program_state &&
|
||||
memcmp (¤t_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
|
||||
return;
|
||||
|
||||
if (builder->render_ops->len > 0)
|
||||
{
|
||||
last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_CLIP)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
|
||||
|
||||
if (last_op->op == OP_CHANGE_CLIP)
|
||||
{
|
||||
last_op->clip = *clip;
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderOp op;
|
||||
|
||||
op.op = OP_CHANGE_CLIP;
|
||||
op.clip = *clip;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
}
|
||||
op->clip = *clip;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
current_program_state->clip = *clip;
|
||||
@@ -356,8 +346,8 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
GskTransform *transform)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
graphene_matrix_t matrix;
|
||||
OpMatrix *op;
|
||||
|
||||
#if 0
|
||||
XXX This is not possible if we want pop() to work.
|
||||
@@ -368,26 +358,10 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
|
||||
|
||||
gsk_transform_to_matrix (transform, &matrix);
|
||||
|
||||
if (builder->render_ops->len > 0)
|
||||
{
|
||||
RenderOp *last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
|
||||
if (last_op->op == OP_CHANGE_MODELVIEW)
|
||||
{
|
||||
last_op->modelview = matrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_MODELVIEW;
|
||||
op.modelview = matrix;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_MODELVIEW;
|
||||
op.modelview = matrix;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_MODELVIEW)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_MODELVIEW);
|
||||
|
||||
op->matrix = matrix;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
{
|
||||
@@ -505,29 +479,13 @@ ops_set_projection (RenderOpBuilder *builder,
|
||||
const graphene_matrix_t *projection)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
graphene_matrix_t prev_mv;
|
||||
OpMatrix *op;
|
||||
|
||||
if (builder->render_ops->len > 0)
|
||||
{
|
||||
RenderOp *last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
|
||||
if (last_op->op == OP_CHANGE_PROJECTION)
|
||||
{
|
||||
last_op->projection = *projection;
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_PROJECTION;
|
||||
op.projection = *projection;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_PROJECTION;
|
||||
op.projection = *projection;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_PROJECTION)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_PROJECTION);
|
||||
|
||||
op->matrix = *projection;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
current_program_state->projection = *projection;
|
||||
@@ -543,16 +501,15 @@ ops_set_viewport (RenderOpBuilder *builder,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
OpViewport *op;
|
||||
graphene_rect_t prev_viewport;
|
||||
|
||||
if (current_program_state != NULL &&
|
||||
rect_equal (¤t_program_state->viewport, viewport))
|
||||
return current_program_state->viewport;
|
||||
|
||||
op.op = OP_CHANGE_VIEWPORT;
|
||||
op.viewport = *viewport;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_CHANGE_VIEWPORT);
|
||||
op->viewport = *viewport;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
current_program_state->viewport = *viewport;
|
||||
@@ -567,14 +524,13 @@ void
|
||||
ops_set_texture (RenderOpBuilder *builder,
|
||||
int texture_id)
|
||||
{
|
||||
RenderOp op;
|
||||
OpTexture *op;
|
||||
|
||||
if (builder->current_texture == texture_id)
|
||||
return;
|
||||
|
||||
op.op = OP_CHANGE_SOURCE_TEXTURE;
|
||||
op.texture_id = texture_id;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_CHANGE_SOURCE_TEXTURE);
|
||||
op->texture_id = texture_id;
|
||||
builder->current_texture = texture_id;
|
||||
}
|
||||
|
||||
@@ -582,7 +538,7 @@ int
|
||||
ops_set_render_target (RenderOpBuilder *builder,
|
||||
int render_target_id)
|
||||
{
|
||||
RenderOp op;
|
||||
OpRenderTarget *op;
|
||||
int prev_render_target;
|
||||
|
||||
if (builder->current_render_target == render_target_id)
|
||||
@@ -590,26 +546,10 @@ ops_set_render_target (RenderOpBuilder *builder,
|
||||
|
||||
prev_render_target = builder->current_render_target;
|
||||
|
||||
if (builder->render_ops->len > 0)
|
||||
{
|
||||
RenderOp *last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
|
||||
if (last_op->op == OP_CHANGE_RENDER_TARGET)
|
||||
{
|
||||
last_op->render_target_id = render_target_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_RENDER_TARGET;
|
||||
op.render_target_id = render_target_id;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_RENDER_TARGET;
|
||||
op.render_target_id = render_target_id;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_RENDER_TARGET)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_RENDER_TARGET);
|
||||
|
||||
op->render_target_id = render_target_id;
|
||||
|
||||
builder->current_render_target = render_target_id;
|
||||
|
||||
@@ -621,34 +561,16 @@ ops_set_opacity (RenderOpBuilder *builder,
|
||||
float opacity)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
OpOpacity *op;
|
||||
float prev_opacity;
|
||||
RenderOp *last_op;
|
||||
|
||||
if (builder->current_opacity == opacity)
|
||||
return opacity;
|
||||
|
||||
if (builder->render_ops->len > 0)
|
||||
{
|
||||
last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
|
||||
if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_OPACITY)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_OPACITY);
|
||||
|
||||
if (last_op->op == OP_CHANGE_OPACITY)
|
||||
{
|
||||
last_op->opacity = opacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_OPACITY;
|
||||
op.opacity = opacity;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
op.op = OP_CHANGE_OPACITY;
|
||||
op.opacity = opacity;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
}
|
||||
op->opacity = opacity;
|
||||
|
||||
prev_opacity = builder->current_opacity;
|
||||
builder->current_opacity = opacity;
|
||||
@@ -664,16 +586,15 @@ ops_set_color (RenderOpBuilder *builder,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
OpColor *op;
|
||||
|
||||
if (gdk_rgba_equal (color, ¤t_program_state->color))
|
||||
return;
|
||||
|
||||
current_program_state->color = *color;
|
||||
|
||||
op.op = OP_CHANGE_COLOR;
|
||||
op.color = *color;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_CHANGE_COLOR);
|
||||
op->rgba = *color;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -682,7 +603,7 @@ ops_set_color_matrix (RenderOpBuilder *builder,
|
||||
const graphene_vec4_t *offset)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
OpColorMatrix *op;
|
||||
|
||||
if (memcmp (matrix,
|
||||
¤t_program_state->color_matrix.matrix,
|
||||
@@ -695,10 +616,9 @@ ops_set_color_matrix (RenderOpBuilder *builder,
|
||||
current_program_state->color_matrix.matrix = *matrix;
|
||||
current_program_state->color_matrix.offset = *offset;
|
||||
|
||||
op.op = OP_CHANGE_COLOR_MATRIX;
|
||||
op.color_matrix.matrix = *matrix;
|
||||
op.color_matrix.offset = *offset;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_CHANGE_COLOR_MATRIX);
|
||||
op->matrix = *matrix;
|
||||
op->offset = *offset;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -706,7 +626,7 @@ ops_set_border (RenderOpBuilder *builder,
|
||||
const GskRoundedRect *outline)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
OpBorder *op;
|
||||
|
||||
if (memcmp (¤t_program_state->border.outline,
|
||||
outline, sizeof (GskRoundedRect)) == 0)
|
||||
@@ -714,9 +634,8 @@ ops_set_border (RenderOpBuilder *builder,
|
||||
|
||||
current_program_state->border.outline = *outline;
|
||||
|
||||
op.op = OP_CHANGE_BORDER;
|
||||
op.border.outline = *outline;
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_CHANGE_BORDER);
|
||||
op->outline = *outline;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -724,7 +643,7 @@ ops_set_border_width (RenderOpBuilder *builder,
|
||||
const float *widths)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
OpBorder *op;
|
||||
|
||||
if (memcmp (current_program_state->border.widths,
|
||||
widths, sizeof (float) * 4) == 0)
|
||||
@@ -733,13 +652,11 @@ ops_set_border_width (RenderOpBuilder *builder,
|
||||
memcpy (¤t_program_state->border.widths,
|
||||
widths, sizeof (float) * 4);
|
||||
|
||||
op.op = OP_CHANGE_BORDER_WIDTH;
|
||||
op.border.widths[0] = widths[0];
|
||||
op.border.widths[1] = widths[1];
|
||||
op.border.widths[2] = widths[2];
|
||||
op.border.widths[3] = widths[3];
|
||||
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = ops_begin (builder, OP_CHANGE_BORDER_WIDTH);
|
||||
op->widths[0] = widths[0];
|
||||
op->widths[1] = widths[1];
|
||||
op->widths[2] = widths[2];
|
||||
op->widths[3] = widths[3];
|
||||
}
|
||||
|
||||
void
|
||||
@@ -747,66 +664,37 @@ ops_set_border_color (RenderOpBuilder *builder,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
ProgramState *current_program_state = get_current_program_state (builder);
|
||||
RenderOp op;
|
||||
op.op = OP_CHANGE_BORDER_COLOR;
|
||||
rgba_to_float (color, op.border.color);
|
||||
OpBorder *op;
|
||||
float fcolor[4];
|
||||
|
||||
if (memcmp (&op.border.color, ¤t_program_state->border.color,
|
||||
sizeof (float) * 4) == 0)
|
||||
rgba_to_float (color, fcolor);
|
||||
|
||||
if (memcmp (fcolor, ¤t_program_state->border.color, sizeof fcolor) == 0)
|
||||
return;
|
||||
|
||||
rgba_to_float (color, current_program_state->border.color);
|
||||
|
||||
g_array_append_val (builder->render_ops, op);
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_BORDER_COLOR);
|
||||
memcpy (op->color, fcolor, sizeof (float[4]));
|
||||
memcpy (current_program_state->border.color, fcolor, sizeof (float[4]));
|
||||
}
|
||||
|
||||
void
|
||||
ops_draw (RenderOpBuilder *builder,
|
||||
const GskQuadVertex vertex_data[GL_N_VERTICES])
|
||||
{
|
||||
RenderOp *last_op;
|
||||
OpDraw *op;
|
||||
|
||||
last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
|
||||
/* If the previous op was a DRAW as well, we didn't change anything between the two calls,
|
||||
* so these are just 2 subsequent draw calls. Same VAO, same program etc.
|
||||
* And the offsets into the vao are in order as well, so make it one draw call. */
|
||||
if (last_op->op == OP_DRAW)
|
||||
if ((op = op_buffer_peek_tail_checked (&builder->render_ops, OP_DRAW)))
|
||||
{
|
||||
/* We allow ourselves a little trick here. We still have to add a CHANGE_VAO op for
|
||||
* this draw call so we can add our vertex data there, but we want it to be placed before
|
||||
* the last draw call, so we reorder those. */
|
||||
RenderOp new_draw;
|
||||
new_draw.op = OP_DRAW;
|
||||
new_draw.draw.vao_offset = last_op->draw.vao_offset;
|
||||
new_draw.draw.vao_size = last_op->draw.vao_size + GL_N_VERTICES;
|
||||
|
||||
last_op->op = OP_CHANGE_VAO;
|
||||
memcpy (&last_op->vertex_data, vertex_data, sizeof(GskQuadVertex) * GL_N_VERTICES);
|
||||
|
||||
/* Now add the DRAW */
|
||||
g_array_append_val (builder->render_ops, new_draw);
|
||||
op->vao_size += GL_N_VERTICES;
|
||||
}
|
||||
else
|
||||
{
|
||||
const gsize n_ops = builder->render_ops->len;
|
||||
RenderOp *op;
|
||||
gsize offset = builder->buffer_size / sizeof (GskQuadVertex);
|
||||
|
||||
/* We will add two render ops here. */
|
||||
g_array_set_size (builder->render_ops, n_ops + 2);
|
||||
|
||||
op = &g_array_index (builder->render_ops, RenderOp, n_ops);
|
||||
op->op = OP_CHANGE_VAO;
|
||||
memcpy (&op->vertex_data, vertex_data, sizeof(GskQuadVertex) * GL_N_VERTICES);
|
||||
|
||||
op = &g_array_index (builder->render_ops, RenderOp, n_ops + 1);
|
||||
op->op = OP_DRAW;
|
||||
op->draw.vao_offset = offset;
|
||||
op->draw.vao_size = GL_N_VERTICES;
|
||||
op = op_buffer_add (&builder->render_ops, OP_DRAW);
|
||||
op->vao_offset = builder->vertices->len;
|
||||
op->vao_size = GL_N_VERTICES;
|
||||
}
|
||||
|
||||
/* We added new vertex data in both cases so increase the buffer size */
|
||||
builder->buffer_size += sizeof (GskQuadVertex) * GL_N_VERTICES;
|
||||
g_array_append_vals (builder->vertices, vertex_data, GL_N_VERTICES);
|
||||
}
|
||||
|
||||
/* The offset is only valid for the current modelview.
|
||||
@@ -821,9 +709,22 @@ ops_offset (RenderOpBuilder *builder,
|
||||
builder->dy += y;
|
||||
}
|
||||
|
||||
void
|
||||
ops_add (RenderOpBuilder *builder,
|
||||
const RenderOp *op)
|
||||
gpointer
|
||||
ops_begin (RenderOpBuilder *builder,
|
||||
OpKind kind)
|
||||
{
|
||||
g_array_append_val (builder->render_ops, *op);
|
||||
return op_buffer_add (&builder->render_ops, kind);
|
||||
}
|
||||
|
||||
void
|
||||
ops_reset (RenderOpBuilder *builder)
|
||||
{
|
||||
op_buffer_clear (&builder->render_ops);
|
||||
g_array_set_size (builder->vertices, 0);
|
||||
}
|
||||
|
||||
OpBuffer *
|
||||
ops_get_buffer (RenderOpBuilder *builder)
|
||||
{
|
||||
return &builder->render_ops;
|
||||
}
|
||||
|
||||
+10
-131
@@ -10,6 +10,8 @@
|
||||
#include "gskglrenderer.h"
|
||||
#include "gskrendernodeprivate.h"
|
||||
|
||||
#include "opbuffer.h"
|
||||
|
||||
#define GL_N_VERTICES 6
|
||||
#define GL_N_PROGRAMS 13
|
||||
|
||||
@@ -32,38 +34,7 @@ typedef struct
|
||||
OpsMatrixMetadata metadata;
|
||||
} MatrixStackEntry;
|
||||
|
||||
enum {
|
||||
OP_NONE,
|
||||
OP_CHANGE_OPACITY = 1,
|
||||
OP_CHANGE_COLOR = 2,
|
||||
OP_CHANGE_PROJECTION = 3,
|
||||
OP_CHANGE_MODELVIEW = 4,
|
||||
OP_CHANGE_PROGRAM = 5,
|
||||
OP_CHANGE_RENDER_TARGET = 6,
|
||||
OP_CHANGE_CLIP = 7,
|
||||
OP_CHANGE_VIEWPORT = 8,
|
||||
OP_CHANGE_SOURCE_TEXTURE = 9,
|
||||
OP_CHANGE_VAO = 10,
|
||||
OP_CHANGE_LINEAR_GRADIENT = 11,
|
||||
OP_CHANGE_COLOR_MATRIX = 12,
|
||||
OP_CHANGE_BLUR = 13,
|
||||
OP_CHANGE_INSET_SHADOW = 14,
|
||||
OP_CHANGE_OUTSET_SHADOW = 15,
|
||||
OP_CHANGE_BORDER = 16,
|
||||
OP_CHANGE_BORDER_COLOR = 17,
|
||||
OP_CHANGE_BORDER_WIDTH = 18,
|
||||
OP_CHANGE_CROSS_FADE = 19,
|
||||
OP_CHANGE_UNBLURRED_OUTSET_SHADOW = 20,
|
||||
OP_CLEAR = 21,
|
||||
OP_DRAW = 22,
|
||||
OP_DUMP_FRAMEBUFFER = 23,
|
||||
OP_PUSH_DEBUG_GROUP = 24,
|
||||
OP_POP_DEBUG_GROUP = 25,
|
||||
OP_CHANGE_BLEND = 26,
|
||||
OP_CHANGE_REPEAT = 27,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct _Program
|
||||
{
|
||||
int index; /* Into the renderer's program array */
|
||||
|
||||
@@ -145,101 +116,7 @@ typedef struct
|
||||
int texture_rect_location;
|
||||
} repeat;
|
||||
};
|
||||
|
||||
} Program;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint op;
|
||||
|
||||
union {
|
||||
float opacity;
|
||||
graphene_matrix_t modelview;
|
||||
graphene_matrix_t projection;
|
||||
const Program *program;
|
||||
int texture_id;
|
||||
int render_target_id;
|
||||
GdkRGBA color;
|
||||
GskQuadVertex vertex_data[6];
|
||||
GskRoundedRect clip;
|
||||
graphene_rect_t viewport;
|
||||
struct {
|
||||
int n_color_stops;
|
||||
float color_offsets[8];
|
||||
float color_stops[4 * 8];
|
||||
graphene_point_t start_point;
|
||||
graphene_point_t end_point;
|
||||
} linear_gradient;
|
||||
struct {
|
||||
gsize vao_offset;
|
||||
gsize vao_size;
|
||||
} draw;
|
||||
struct {
|
||||
graphene_matrix_t matrix;
|
||||
graphene_vec4_t offset;
|
||||
} color_matrix;
|
||||
struct {
|
||||
float radius;
|
||||
graphene_size_t size;
|
||||
float dir[2];
|
||||
} blur;
|
||||
struct {
|
||||
float outline[4];
|
||||
float corner_widths[4];
|
||||
float corner_heights[4];
|
||||
float radius;
|
||||
float spread;
|
||||
float offset[2];
|
||||
float color[4];
|
||||
} inset_shadow;
|
||||
struct {
|
||||
float outline[4];
|
||||
float corner_widths[4];
|
||||
float corner_heights[4];
|
||||
float radius;
|
||||
float spread;
|
||||
float offset[2];
|
||||
float color[4];
|
||||
} outset_shadow;
|
||||
struct {
|
||||
float outline[4];
|
||||
float corner_widths[4];
|
||||
float corner_heights[4];
|
||||
float radius;
|
||||
float spread;
|
||||
float offset[2];
|
||||
float color[4];
|
||||
} unblurred_outset_shadow;
|
||||
struct {
|
||||
float color[4];
|
||||
} shadow;
|
||||
struct {
|
||||
float widths[4];
|
||||
float color[4];
|
||||
GskRoundedRect outline;
|
||||
} border;
|
||||
struct {
|
||||
float progress;
|
||||
int source2;
|
||||
} cross_fade;
|
||||
struct {
|
||||
int source2;
|
||||
int mode;
|
||||
} blend;
|
||||
struct {
|
||||
float child_bounds[4];
|
||||
float texture_rect[4];
|
||||
} repeat;
|
||||
struct {
|
||||
char *filename;
|
||||
int width;
|
||||
int height;
|
||||
} dump;
|
||||
struct {
|
||||
char text[180]; /* Size of linear_gradient, so 'should be enough' without growing RenderOp */
|
||||
} debug_group;
|
||||
};
|
||||
} RenderOp;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -276,9 +153,9 @@ typedef struct
|
||||
float current_opacity;
|
||||
float dx, dy;
|
||||
|
||||
gsize buffer_size;
|
||||
OpBuffer render_ops;
|
||||
GArray *vertices;
|
||||
|
||||
GArray *render_ops;
|
||||
GskGLRenderer *renderer;
|
||||
|
||||
/* Stack of modelview matrices */
|
||||
@@ -298,6 +175,7 @@ void ops_dump_framebuffer (RenderOpBuilder *builder,
|
||||
int height);
|
||||
void ops_init (RenderOpBuilder *builder);
|
||||
void ops_free (RenderOpBuilder *builder);
|
||||
void ops_reset (RenderOpBuilder *builder);
|
||||
void ops_push_debug_group (RenderOpBuilder *builder,
|
||||
const char *text);
|
||||
void ops_pop_debug_group (RenderOpBuilder *builder);
|
||||
@@ -358,7 +236,8 @@ void ops_offset (RenderOpBuilder *builder,
|
||||
float x,
|
||||
float y);
|
||||
|
||||
void ops_add (RenderOpBuilder *builder,
|
||||
const RenderOp *op);
|
||||
gpointer ops_begin (RenderOpBuilder *builder,
|
||||
OpKind kind);
|
||||
OpBuffer *ops_get_buffer (RenderOpBuilder *builder);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "gskglshadowcacheprivate.h"
|
||||
|
||||
#define MAX_UNUSED_FRAMES (16 * 5) /* 5 seconds? */
|
||||
#define MAX_UNUSED_FRAMES (16 * 5)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -62,9 +62,6 @@ gsk_gl_shadow_cache_begin_frame (GskGLShadowCache *self,
|
||||
{
|
||||
guint i, p;
|
||||
|
||||
/* We remove all textures with used = FALSE since those have not been used in the
|
||||
* last frame. For all others, we reset the `used` value to FALSE instead and see
|
||||
* if they end up with TRUE in the next call to begin_frame. */
|
||||
for (i = 0, p = self->textures->len; i < p; i ++)
|
||||
{
|
||||
CacheItem *item = &g_array_index (self->textures, CacheItem, i);
|
||||
|
||||
@@ -74,7 +74,8 @@ write_atlas_to_png (GskGLTextureAtlas *atlas,
|
||||
#endif
|
||||
|
||||
void
|
||||
gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self)
|
||||
gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self,
|
||||
GPtrArray *removed)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -86,7 +87,7 @@ gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self)
|
||||
{
|
||||
GSK_NOTE(GLYPH_CACHE,
|
||||
g_message ("Dropping atlas %d (%g.2%% old)", i,
|
||||
gsk_gl_texture_atlas_get_unused_ratio (atlas)));
|
||||
100.0 * gsk_gl_texture_atlas_get_unused_ratio (atlas)));
|
||||
|
||||
if (atlas->texture_id != 0)
|
||||
{
|
||||
@@ -94,10 +95,18 @@ gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self)
|
||||
atlas->texture_id = 0;
|
||||
}
|
||||
|
||||
g_ptr_array_add (removed, atlas);
|
||||
g_ptr_array_remove_index (self->atlases, i);
|
||||
}
|
||||
}
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, {
|
||||
static guint timestamp;
|
||||
if (timestamp++ % 60 == 0)
|
||||
g_message ("%d atlases", self->atlases->len);
|
||||
});
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
static guint timestamp;
|
||||
@@ -158,6 +167,8 @@ gsk_gl_texture_atlases_pack (GskGLTextureAtlases *self,
|
||||
|
||||
/* Pack it onto that one, which surely has enough space... */
|
||||
gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y);
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, g_message ("adding new atlas"));
|
||||
}
|
||||
|
||||
*atlas_out = atlas;
|
||||
|
||||
@@ -35,7 +35,8 @@ GskGLTextureAtlases *gsk_gl_texture_atlases_new (void);
|
||||
GskGLTextureAtlases *gsk_gl_texture_atlases_ref (GskGLTextureAtlases *atlases);
|
||||
void gsk_gl_texture_atlases_unref (GskGLTextureAtlases *atlases);
|
||||
|
||||
void gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *atlases);
|
||||
void gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *atlases,
|
||||
GPtrArray *removed);
|
||||
gboolean gsk_gl_texture_atlases_pack (GskGLTextureAtlases *atlases,
|
||||
int width,
|
||||
int height,
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "opbuffer.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static guint op_sizes[OP_LAST] = {
|
||||
0,
|
||||
sizeof (OpOpacity),
|
||||
sizeof (OpColor),
|
||||
sizeof (OpMatrix),
|
||||
sizeof (OpMatrix),
|
||||
sizeof (OpProgram),
|
||||
sizeof (OpRenderTarget),
|
||||
sizeof (OpClip),
|
||||
sizeof (OpViewport),
|
||||
sizeof (OpTexture),
|
||||
sizeof (OpRepeat),
|
||||
sizeof (OpLinearGradient),
|
||||
sizeof (OpColorMatrix),
|
||||
sizeof (OpBlur),
|
||||
sizeof (OpShadow),
|
||||
sizeof (OpShadow),
|
||||
sizeof (OpBorder),
|
||||
sizeof (OpBorder),
|
||||
sizeof (OpBorder),
|
||||
sizeof (OpCrossFade),
|
||||
sizeof (OpShadow),
|
||||
0,
|
||||
sizeof (OpDraw),
|
||||
sizeof (OpDumpFrameBuffer),
|
||||
sizeof (OpDebugGroup),
|
||||
0,
|
||||
sizeof (OpBlend),
|
||||
};
|
||||
|
||||
void
|
||||
op_buffer_init (OpBuffer *buffer)
|
||||
{
|
||||
static gsize initialized = FALSE;
|
||||
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (op_sizes); i++)
|
||||
{
|
||||
guint size = op_sizes[i];
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
/* Round all op entry sizes to the nearest 16 to ensure
|
||||
* that we guarantee proper alignments for all op entries.
|
||||
* This is only done once on first use.
|
||||
*/
|
||||
#define CHECK_SIZE(s) else if (size < (s)) { size = s; }
|
||||
if (0) {}
|
||||
CHECK_SIZE (16)
|
||||
CHECK_SIZE (32)
|
||||
CHECK_SIZE (48)
|
||||
CHECK_SIZE (64)
|
||||
CHECK_SIZE (80)
|
||||
CHECK_SIZE (96)
|
||||
CHECK_SIZE (112)
|
||||
CHECK_SIZE (128)
|
||||
CHECK_SIZE (144)
|
||||
CHECK_SIZE (160)
|
||||
CHECK_SIZE (176)
|
||||
CHECK_SIZE (192)
|
||||
else g_assert_not_reached ();
|
||||
#undef CHECK_SIZE
|
||||
|
||||
op_sizes[i] = size;
|
||||
}
|
||||
}
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
}
|
||||
|
||||
memset (buffer, 0, sizeof *buffer);
|
||||
|
||||
buffer->buflen = 4096;
|
||||
buffer->bufpos = 0;
|
||||
buffer->buf = g_malloc (buffer->buflen);
|
||||
buffer->index = g_array_new (FALSE, FALSE, sizeof (OpBufferEntry));
|
||||
|
||||
/* Add dummy entry to guarantee non-empty index */
|
||||
op_buffer_add (buffer, OP_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
op_buffer_destroy (OpBuffer *buffer)
|
||||
{
|
||||
g_free (buffer->buf);
|
||||
g_array_unref (buffer->index);
|
||||
}
|
||||
|
||||
void
|
||||
op_buffer_clear (OpBuffer *buffer)
|
||||
{
|
||||
if (buffer->index->len > 1)
|
||||
g_array_remove_range (buffer->index, 1, buffer->index->len - 1);
|
||||
buffer->bufpos = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ensure_buffer_space_for (OpBuffer *buffer,
|
||||
guint size)
|
||||
{
|
||||
if G_UNLIKELY (buffer->bufpos + size >= buffer->buflen)
|
||||
{
|
||||
buffer->buflen *= 2;
|
||||
buffer->buf = g_realloc (buffer->buf, buffer->buflen);
|
||||
}
|
||||
}
|
||||
|
||||
gpointer
|
||||
op_buffer_add (OpBuffer *buffer,
|
||||
OpKind kind)
|
||||
{
|
||||
guint size = op_sizes[kind];
|
||||
OpBufferEntry entry;
|
||||
|
||||
entry.pos = buffer->bufpos;
|
||||
entry.kind = kind;
|
||||
|
||||
if (size > 0)
|
||||
ensure_buffer_space_for (buffer, size);
|
||||
|
||||
g_array_append_val (buffer->index, entry);
|
||||
|
||||
buffer->bufpos += size;
|
||||
|
||||
return &buffer->buf[entry.pos];
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
#ifndef __OP_BUFFER_H__
|
||||
#define __OP_BUFFER_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gsk/gsk.h>
|
||||
#include <graphene.h>
|
||||
|
||||
#include "gskgldriverprivate.h"
|
||||
|
||||
typedef struct _Program Program;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OP_NONE = 0,
|
||||
OP_CHANGE_OPACITY = 1,
|
||||
OP_CHANGE_COLOR = 2,
|
||||
OP_CHANGE_PROJECTION = 3,
|
||||
OP_CHANGE_MODELVIEW = 4,
|
||||
OP_CHANGE_PROGRAM = 5,
|
||||
OP_CHANGE_RENDER_TARGET = 6,
|
||||
OP_CHANGE_CLIP = 7,
|
||||
OP_CHANGE_VIEWPORT = 8,
|
||||
OP_CHANGE_SOURCE_TEXTURE = 9,
|
||||
OP_CHANGE_REPEAT = 10,
|
||||
OP_CHANGE_LINEAR_GRADIENT = 11,
|
||||
OP_CHANGE_COLOR_MATRIX = 12,
|
||||
OP_CHANGE_BLUR = 13,
|
||||
OP_CHANGE_INSET_SHADOW = 14,
|
||||
OP_CHANGE_OUTSET_SHADOW = 15,
|
||||
OP_CHANGE_BORDER = 16,
|
||||
OP_CHANGE_BORDER_COLOR = 17,
|
||||
OP_CHANGE_BORDER_WIDTH = 18,
|
||||
OP_CHANGE_CROSS_FADE = 19,
|
||||
OP_CHANGE_UNBLURRED_OUTSET_SHADOW = 20,
|
||||
OP_CLEAR = 21,
|
||||
OP_DRAW = 22,
|
||||
OP_DUMP_FRAMEBUFFER = 23,
|
||||
OP_PUSH_DEBUG_GROUP = 24,
|
||||
OP_POP_DEBUG_GROUP = 25,
|
||||
OP_CHANGE_BLEND = 26,
|
||||
OP_LAST
|
||||
} OpKind;
|
||||
|
||||
/* OpNode are allocated within OpBuffer.pos, but we keep
|
||||
* a secondary index into the locations of that buffer
|
||||
* from OpBuffer.index. This allows peeking at the kind
|
||||
* and quickly replacing existing entries when necessary.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
guint pos;
|
||||
OpKind kind;
|
||||
} OpBufferEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint8 *buf;
|
||||
gsize buflen;
|
||||
gsize bufpos;
|
||||
GArray *index;
|
||||
} OpBuffer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float opacity;
|
||||
} OpOpacity;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
} OpMatrix;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const Program *program;
|
||||
} OpProgram;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
} OpColor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int render_target_id;
|
||||
} OpRenderTarget;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GskRoundedRect clip;
|
||||
} OpClip;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
graphene_rect_t viewport;
|
||||
} OpViewport;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int texture_id;
|
||||
} OpTexture;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gsize vao_offset;
|
||||
gsize vao_size;
|
||||
} OpDraw;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float color_offsets[8];
|
||||
float color_stops[4 * 8];
|
||||
graphene_point_t start_point;
|
||||
graphene_point_t end_point;
|
||||
int n_color_stops;
|
||||
} OpLinearGradient;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
graphene_matrix_t matrix;
|
||||
graphene_vec4_t offset;
|
||||
} OpColorMatrix;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float radius;
|
||||
graphene_size_t size;
|
||||
float dir[2];
|
||||
} OpBlur;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float outline[4];
|
||||
float corner_widths[4];
|
||||
float corner_heights[4];
|
||||
float radius;
|
||||
float spread;
|
||||
float offset[2];
|
||||
float color[4];
|
||||
} OpShadow;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float widths[4];
|
||||
float color[4];
|
||||
GskRoundedRect outline;
|
||||
} OpBorder;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float progress;
|
||||
int source2;
|
||||
} OpCrossFade;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *filename;
|
||||
int width;
|
||||
int height;
|
||||
} OpDumpFrameBuffer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char text[64];
|
||||
} OpDebugGroup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int source2;
|
||||
int mode;
|
||||
} OpBlend;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float child_bounds[4];
|
||||
float texture_rect[4];
|
||||
} OpRepeat;
|
||||
|
||||
void op_buffer_init (OpBuffer *buffer);
|
||||
void op_buffer_destroy (OpBuffer *buffer);
|
||||
void op_buffer_clear (OpBuffer *buffer);
|
||||
gpointer op_buffer_add (OpBuffer *buffer,
|
||||
OpKind kind);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GArray *index;
|
||||
OpBuffer *buffer;
|
||||
guint pos;
|
||||
} OpBufferIter;
|
||||
|
||||
static inline void
|
||||
op_buffer_iter_init (OpBufferIter *iter,
|
||||
OpBuffer *buffer)
|
||||
{
|
||||
iter->index = buffer->index;
|
||||
iter->buffer = buffer;
|
||||
iter->pos = 1; /* Skip first OP_NONE */
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
op_buffer_iter_next (OpBufferIter *iter,
|
||||
OpKind *kind)
|
||||
{
|
||||
const OpBufferEntry *entry;
|
||||
|
||||
if (iter->pos == iter->index->len)
|
||||
return NULL;
|
||||
|
||||
entry = &g_array_index (iter->index, OpBufferEntry, iter->pos);
|
||||
|
||||
iter->pos++;
|
||||
|
||||
*kind = entry->kind;
|
||||
return &iter->buffer->buf[entry->pos];
|
||||
}
|
||||
|
||||
static inline void
|
||||
op_buffer_pop_tail (OpBuffer *buffer)
|
||||
{
|
||||
/* Never truncate the first OP_NONE */
|
||||
if G_LIKELY (buffer->index->len > 0)
|
||||
buffer->index->len--;
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
op_buffer_peek_tail (OpBuffer *buffer,
|
||||
OpKind *kind)
|
||||
{
|
||||
const OpBufferEntry *entry;
|
||||
|
||||
entry = &g_array_index (buffer->index, OpBufferEntry, buffer->index->len - 1);
|
||||
*kind = entry->kind;
|
||||
return &buffer->buf[entry->pos];
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
op_buffer_peek_tail_checked (OpBuffer *buffer,
|
||||
OpKind kind)
|
||||
{
|
||||
const OpBufferEntry *entry;
|
||||
|
||||
entry = &g_array_index (buffer->index, OpBufferEntry, buffer->index->len - 1);
|
||||
|
||||
if (entry->kind == kind)
|
||||
return &buffer->buf[entry->pos];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline guint
|
||||
op_buffer_n_ops (OpBuffer *buffer)
|
||||
{
|
||||
return buffer->index->len - 1;
|
||||
}
|
||||
|
||||
#endif /* __OP_BUFFER_H__ */
|
||||
@@ -295,6 +295,7 @@ GskRenderNode * gsk_text_node_new (PangoFont
|
||||
const graphene_point_t *offset);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
PangoFont * gsk_text_node_peek_font (GskRenderNode *node);
|
||||
gboolean gsk_text_node_has_color_glyphs (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gsk_text_node_get_num_glyphs (GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
+30
-6
@@ -28,6 +28,7 @@
|
||||
#include "gsktransformprivate.h"
|
||||
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include <cairo-ft.h>
|
||||
|
||||
static void
|
||||
rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
|
||||
@@ -3408,6 +3409,7 @@ struct _GskTextNode
|
||||
GskRenderNode render_node;
|
||||
|
||||
PangoFont *font;
|
||||
gboolean has_color_glyphs;
|
||||
|
||||
GdkRGBA color;
|
||||
graphene_point_t offset;
|
||||
@@ -3424,12 +3426,6 @@ gsk_text_node_finalize (GskRenderNode *node)
|
||||
g_object_unref (self->font);
|
||||
}
|
||||
|
||||
#ifndef STACK_BUFFER_SIZE
|
||||
#define STACK_BUFFER_SIZE (512 * sizeof (int))
|
||||
#endif
|
||||
|
||||
#define STACK_ARRAY_LENGTH(T) (STACK_BUFFER_SIZE / sizeof(T))
|
||||
|
||||
static void
|
||||
gsk_text_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
@@ -3497,6 +3493,23 @@ static const GskRenderNodeClass GSK_TEXT_NODE_CLASS = {
|
||||
gsk_text_node_diff,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
font_has_color_glyphs (const PangoFont *font)
|
||||
{
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
gboolean has_color = FALSE;
|
||||
|
||||
scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font);
|
||||
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_FT)
|
||||
{
|
||||
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
|
||||
has_color = (FT_HAS_COLOR (ft_face) != 0);
|
||||
cairo_ft_scaled_font_unlock_face (scaled_font);
|
||||
}
|
||||
|
||||
return has_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_text_node_new:
|
||||
* @font: the #PangoFont containing the glyphs
|
||||
@@ -3529,6 +3542,7 @@ gsk_text_node_new (PangoFont *font,
|
||||
self = (GskTextNode *) gsk_render_node_new (&GSK_TEXT_NODE_CLASS, sizeof (PangoGlyphInfo) * glyphs->num_glyphs);
|
||||
|
||||
self->font = g_object_ref (font);
|
||||
self->has_color_glyphs = font_has_color_glyphs (font);
|
||||
self->color = *color;
|
||||
self->offset = *offset;
|
||||
self->num_glyphs = glyphs->num_glyphs;
|
||||
@@ -3571,6 +3585,16 @@ gsk_text_node_peek_font (GskRenderNode *node)
|
||||
return self->font;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_text_node_has_color_glyphs (GskRenderNode *node)
|
||||
{
|
||||
GskTextNode *self = (GskTextNode *) node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_TEXT_NODE), FALSE);
|
||||
|
||||
return self->has_color_glyphs;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_text_node_get_num_glyphs (GskRenderNode *node)
|
||||
{
|
||||
|
||||
@@ -644,7 +644,7 @@ create_ascii_glyphs (PangoFont *font)
|
||||
PangoLanguage *language = pango_language_from_string ("en_US"); /* just pick one */
|
||||
PangoCoverage *coverage;
|
||||
PangoAnalysis not_a_hack = {
|
||||
.shape_engine = pango_font_find_shaper (font, language, MIN_ASCII_GLYPH), /* never changes */
|
||||
.shape_engine = NULL, /* unused */
|
||||
.lang_engine = NULL, /* unused by pango_shape() */
|
||||
.font = font,
|
||||
.level = 0,
|
||||
|
||||
+2
-2
@@ -1667,8 +1667,8 @@ gsk_transform_new (void)
|
||||
* @out_rect: (out caller-allocates): return location for the bounds
|
||||
* of the transformed rectangle
|
||||
*
|
||||
* Transforms a #graphene_rect_t using the given matrix @m. The
|
||||
* result is the bounding box containing the coplanar quad.
|
||||
* Transforms a #graphene_rect_t using the given transform @self.
|
||||
* The result is the bounding box containing the coplanar quad.
|
||||
**/
|
||||
void
|
||||
gsk_transform_transform_bounds (GskTransform *self,
|
||||
|
||||
@@ -48,6 +48,7 @@ gsk_private_sources = files([
|
||||
'gl/gskglnodesample.c',
|
||||
'gl/gskgltextureatlas.c',
|
||||
'gl/gskgliconcache.c',
|
||||
'gl/opbuffer.c',
|
||||
'gl/stb_rect_pack.c',
|
||||
])
|
||||
|
||||
|
||||
@@ -80,8 +80,24 @@ RoundedRect
|
||||
rounded_rect_shrink (RoundedRect r, vec4 amount)
|
||||
{
|
||||
vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
|
||||
vec4 new_widths = max (r.corner_widths - amount.wyyw, 0.0);
|
||||
vec4 new_heights = max (r.corner_heights - amount.xxzz, 0.0);
|
||||
vec4 new_widths = vec4(0);
|
||||
vec4 new_heights = vec4(0);
|
||||
|
||||
// Left top
|
||||
if (r.corner_widths.x > 0) new_widths.x = r.corner_widths.x - amount.w;
|
||||
if (r.corner_heights.x > 0) new_heights.x = r.corner_heights.x - amount.x;
|
||||
|
||||
// Top right
|
||||
if (r.corner_widths.y > 0) new_widths.y = r.corner_widths.y - amount.y;
|
||||
if (r.corner_heights.y > 0) new_heights.y = r.corner_heights.y - amount.x;
|
||||
|
||||
// Bottom right
|
||||
if (r.corner_widths.z > 0) new_widths.z = r.corner_widths.z - amount.y;
|
||||
if (r.corner_heights.z > 0) new_heights.z = r.corner_heights.z - amount.z;
|
||||
|
||||
// Bottom left
|
||||
if (r.corner_widths.w > 0) new_widths.w = r.corner_widths.w - amount.w;
|
||||
if (r.corner_heights.w > 0) new_heights.w = r.corner_heights.w - amount.z;
|
||||
|
||||
return RoundedRect (new_bounds, new_widths, new_heights);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,10 @@ void main() {
|
||||
f.x += u_viewport.x;
|
||||
f.y = (u_viewport.y + u_viewport.w) - f.y;
|
||||
|
||||
RoundedRect outline = RoundedRect(vec4(u_outline.xy, u_outline.xy + u_outline.zw),
|
||||
RoundedRect inside = RoundedRect(vec4(u_outline.xy, u_outline.xy + u_outline.zw),
|
||||
u_corner_widths, u_corner_heights);
|
||||
RoundedRect inside = rounded_rect_shrink(outline, vec4(u_spread));
|
||||
|
||||
RoundedRect outline = rounded_rect_shrink(inside, vec4(- u_spread));
|
||||
|
||||
vec2 offset = vec2(u_offset.x, - u_offset.y);
|
||||
vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
|
||||
|
||||
@@ -142,13 +142,15 @@ gsk_vulkan_uploader_get_copy_buffer (GskVulkanUploader *self)
|
||||
void
|
||||
gsk_vulkan_uploader_upload (GskVulkanUploader *self)
|
||||
{
|
||||
VkPipelineStageFlagBits host_and_transfer_bits = VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
|
||||
if (self->before_buffer_barriers->len > 0 || self->before_image_barriers->len > 0)
|
||||
{
|
||||
VkCommandBuffer command_buffer;
|
||||
|
||||
command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
|
||||
vkCmdPipelineBarrier (command_buffer,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | host_and_transfer_bits,
|
||||
VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0,
|
||||
0, NULL,
|
||||
@@ -164,7 +166,7 @@ gsk_vulkan_uploader_upload (GskVulkanUploader *self)
|
||||
{
|
||||
VkCommandBuffer command_buffer = gsk_vulkan_uploader_get_copy_buffer (self);
|
||||
vkCmdPipelineBarrier (command_buffer,
|
||||
VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
host_and_transfer_bits,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0,
|
||||
0, NULL,
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#include "gskvulkanrendererprivate.h"
|
||||
#include "gskprivate.h"
|
||||
|
||||
#include <cairo-ft.h>
|
||||
|
||||
#define ORTHO_NEAR_PLANE -10000
|
||||
#define ORTHO_FAR_PLANE 10000
|
||||
|
||||
@@ -172,7 +170,7 @@ gsk_vulkan_render_pass_new (GdkVulkanContext *context,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.finalLayout = final_layout
|
||||
}
|
||||
},
|
||||
@@ -236,23 +234,6 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
|
||||
g_slice_free (GskVulkanRenderPass, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
font_has_color_glyphs (const PangoFont *font)
|
||||
{
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
gboolean has_color = FALSE;
|
||||
|
||||
scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font);
|
||||
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_FT)
|
||||
{
|
||||
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
|
||||
has_color = (FT_HAS_COLOR (ft_face) != 0);
|
||||
cairo_ft_scaled_font_unlock_face (scaled_font);
|
||||
}
|
||||
|
||||
return has_color;
|
||||
}
|
||||
|
||||
#define FALLBACK(...) G_STMT_START { \
|
||||
GSK_RENDERER_NOTE (gsk_vulkan_render_get_renderer (render), FALLBACK, g_message (__VA_ARGS__)); \
|
||||
goto fallback; \
|
||||
@@ -367,13 +348,14 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||
const PangoFont *font = gsk_text_node_peek_font (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node);
|
||||
guint num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
gboolean has_color_glyphs = gsk_text_node_has_color_glyphs (node);
|
||||
int i;
|
||||
guint count;
|
||||
guint texture_index;
|
||||
gint x_position;
|
||||
GskVulkanRenderer *renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
|
||||
|
||||
if (font_has_color_glyphs (font))
|
||||
if (has_color_glyphs)
|
||||
{
|
||||
if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
|
||||
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_TEXT;
|
||||
|
||||
@@ -513,7 +513,7 @@ gtk_text_view_accessible_get_character_extents (AtkText *text,
|
||||
*height = rectangle.height;
|
||||
*width = rectangle.width;
|
||||
|
||||
gtk_text_view_buffer_to_surface_coords (view, GTK_TEXT_WINDOW_WIDGET,
|
||||
gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
|
||||
rectangle.x, rectangle.y, x, y);
|
||||
if (coords != ATK_XY_WINDOW)
|
||||
{
|
||||
|
||||
@@ -22,13 +22,41 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_stream_scaled (GInputStream *stream,
|
||||
gdouble scale,
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_stream (GInputStream *stream,
|
||||
const char *format,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream,
|
||||
const char *format,
|
||||
int width,
|
||||
int height,
|
||||
gboolean aspect,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_resource_scaled (const gchar *resource_path,
|
||||
gdouble scale,
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_stream_scaled (GInputStream *stream,
|
||||
const char *format,
|
||||
double scale,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_resource (const char *resource_path,
|
||||
const char *format,
|
||||
GError **error);
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_resource_at_scale (const char *resource_path,
|
||||
const char *format,
|
||||
int width,
|
||||
int height,
|
||||
gboolean preserve_aspect,
|
||||
GError **error);
|
||||
GdkPixbuf *_gdk_pixbuf_new_from_resource_scaled (const char *resource_path,
|
||||
const char *format,
|
||||
double scale,
|
||||
GError **error);
|
||||
|
||||
GdkPixbuf *gtk_color_symbolic_pixbuf (GdkPixbuf *symbolic,
|
||||
const GdkRGBA *fg_color,
|
||||
const GdkRGBA *success_color,
|
||||
const GdkRGBA *warning_color,
|
||||
const GdkRGBA *error_color);
|
||||
|
||||
GdkPixbuf *gtk_make_symbolic_pixbuf_from_data (const char *data,
|
||||
gsize len,
|
||||
@@ -41,6 +69,11 @@ GdkPixbuf *gtk_make_symbolic_pixbuf_from_file (GFile *file,
|
||||
int height,
|
||||
double scale,
|
||||
GError **error);
|
||||
GdkPixbuf *gtk_make_symbolic_pixbuf_from_path (const char *path,
|
||||
int width,
|
||||
int height,
|
||||
double scale,
|
||||
GError **error);
|
||||
GdkPixbuf *gtk_make_symbolic_pixbuf_from_resource (const char *path,
|
||||
int width,
|
||||
int height,
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include <gtk/gtkcellrenderertoggle.h>
|
||||
#include <gtk/gtkcellview.h>
|
||||
#include <gtk/gtkcenterbox.h>
|
||||
#include <gtk/gtkcenterlayout.h>
|
||||
#include <gtk/gtkcheckbutton.h>
|
||||
#include <gtk/gtkcheckmenuitem.h>
|
||||
#include <gtk/gtkcolorbutton.h>
|
||||
@@ -165,6 +166,7 @@
|
||||
#include <gtk/gtkmountoperation.h>
|
||||
#include <gtk/gtknative.h>
|
||||
#include <gtk/gtknativedialog.h>
|
||||
#include <gtk/gtknoselection.h>
|
||||
#include <gtk/gtknotebook.h>
|
||||
#include <gtk/gtkorientable.h>
|
||||
#include <gtk/gtkoverlay.h>
|
||||
|
||||
@@ -106,6 +106,16 @@ _gtk_allocated_bitmask_free (GtkBitmask *mask)
|
||||
g_free (mask);
|
||||
}
|
||||
|
||||
char *
|
||||
_gtk_allocated_bitmask_to_string (const GtkBitmask *mask)
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
|
||||
_gtk_allocated_bitmask_print (mask, str);
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_allocated_bitmask_print (const GtkBitmask *mask,
|
||||
GString *string)
|
||||
|
||||
@@ -42,6 +42,7 @@ typedef struct _GtkBitmask GtkBitmask;
|
||||
GtkBitmask * _gtk_allocated_bitmask_copy (const GtkBitmask *mask);
|
||||
void _gtk_allocated_bitmask_free (GtkBitmask *mask);
|
||||
|
||||
char * _gtk_allocated_bitmask_to_string (const GtkBitmask *mask);
|
||||
void _gtk_allocated_bitmask_print (const GtkBitmask *mask,
|
||||
GString *string);
|
||||
|
||||
|
||||
@@ -364,12 +364,28 @@ gtk_app_chooser_button_populate (GtkAppChooserButton *self)
|
||||
|
||||
if (default_app != NULL)
|
||||
{
|
||||
get_first_iter (priv->store, &iter);
|
||||
cycled_recommended = TRUE;
|
||||
/* The default app matches all types and sub-types of the
|
||||
* content type we're looking at, whereas the recomended
|
||||
* apps match the content type exactly. If the default app
|
||||
* does not appear in the recommended apps then we might
|
||||
* end up showing a text editor for calendar-related files,
|
||||
* which is not helpful.
|
||||
*
|
||||
* See: https://gitlab.gnome.org/GNOME/gtk/issues/377
|
||||
*/
|
||||
if (g_list_find (recommended_apps, default_app) != NULL)
|
||||
{
|
||||
get_first_iter (priv->store, &iter);
|
||||
cycled_recommended = TRUE;
|
||||
|
||||
insert_one_application (self, default_app, &iter);
|
||||
insert_one_application (self, default_app, &iter);
|
||||
|
||||
g_object_unref (default_app);
|
||||
g_object_unref (default_app);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_object (&default_app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -322,7 +322,6 @@ build_forget_menu_item (GtkAppChooserDialog *self)
|
||||
GtkWidget *retval;
|
||||
|
||||
retval = gtk_menu_item_new_with_label (_("Forget association"));
|
||||
gtk_widget_show (retval);
|
||||
|
||||
g_signal_connect (retval, "activate",
|
||||
G_CALLBACK (forget_menu_item_activate_cb), self);
|
||||
@@ -504,11 +503,9 @@ setup_search (GtkAppChooserDialog *self)
|
||||
button = gtk_toggle_button_new ();
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
image = gtk_image_new_from_icon_name ("edit-find-symbolic");
|
||||
gtk_widget_show (image);
|
||||
gtk_container_add (GTK_CONTAINER (button), image);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
|
||||
gtk_style_context_remove_class (gtk_widget_get_style_context (button), "text-button");
|
||||
gtk_widget_show (button);
|
||||
|
||||
header = gtk_dialog_get_header_bar (GTK_DIALOG (self));
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkmenu.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -358,8 +358,31 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
|
||||
|
||||
if (dbus->ss_proxy)
|
||||
{
|
||||
GVariant *active_var;
|
||||
gboolean active;
|
||||
|
||||
g_signal_connect (dbus->ss_proxy, "g-signal",
|
||||
G_CALLBACK (screensaver_signal_session), impl->application);
|
||||
|
||||
active_var = g_dbus_proxy_call_sync (dbus->ss_proxy,
|
||||
"GetActive",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
G_MAXINT,
|
||||
NULL,
|
||||
&error);
|
||||
if (!active_var)
|
||||
{
|
||||
g_debug ("Error calling GetActive on GNOME screensaver: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_variant_get (active_var, "(b)", &active);
|
||||
g_variant_unref (active_var);
|
||||
gtk_application_set_screensaver_active (dbus->impl.application, active);
|
||||
}
|
||||
}
|
||||
|
||||
g_debug ("Registering client '%s' '%s'", dbus->application_id, client_id);
|
||||
|
||||
+38
-38
@@ -178,47 +178,47 @@ static void gtk_assistant_page_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void gtk_assistant_buildable_interface_init (GtkBuildableIface *iface);
|
||||
static void gtk_assistant_buildable_add_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const char *type);
|
||||
static gboolean gtk_assistant_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GMarkupParser *parser,
|
||||
gpointer *data);
|
||||
static void gtk_assistant_buildable_custom_finished (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
gpointer user_data);
|
||||
static void gtk_assistant_buildable_interface_init (GtkBuildableIface *iface);
|
||||
static void gtk_assistant_buildable_add_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const char *type);
|
||||
static gboolean gtk_assistant_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GtkBuildableParser *parser,
|
||||
gpointer *data);
|
||||
static void gtk_assistant_buildable_custom_finished (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
gpointer user_data);
|
||||
|
||||
static GList* find_page (GtkAssistant *assistant,
|
||||
GtkWidget *page);
|
||||
static GList* find_page (GtkAssistant *assistant,
|
||||
GtkWidget *page);
|
||||
static void on_assistant_close (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_apply (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_forward (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_back (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_cancel (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_last (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void assistant_remove_page_cb (GtkContainer *container,
|
||||
GtkWidget *page,
|
||||
GtkAssistant *assistant);
|
||||
|
||||
static void on_assistant_close (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_apply (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_forward (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_back (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_cancel (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void on_assistant_last (GtkWidget *widget,
|
||||
GtkAssistant *assistant);
|
||||
static void assistant_remove_page_cb (GtkContainer *container,
|
||||
GtkWidget *page,
|
||||
GtkAssistant *assistant);
|
||||
|
||||
static int gtk_assistant_add_page (GtkAssistant *assistant,
|
||||
GtkAssistantPage *page_info,
|
||||
gint position);
|
||||
static int gtk_assistant_add_page (GtkAssistant *assistant,
|
||||
GtkAssistantPage *page_info,
|
||||
gint position);
|
||||
|
||||
GType _gtk_assistant_accessible_get_type (void);
|
||||
GType _gtk_assistant_accessible_get_type (void);
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -2355,7 +2355,7 @@ gtk_assistant_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GMarkupParser *parser,
|
||||
GtkBuildableParser *parser,
|
||||
gpointer *data)
|
||||
{
|
||||
return parent_buildable_iface->custom_tag_start (buildable, builder, child,
|
||||
|
||||
+355
-98
@@ -67,6 +67,9 @@ typedef enum {
|
||||
typedef struct _GtkBindingEntry GtkBindingEntry;
|
||||
typedef struct _GtkBindingSignal GtkBindingSignal;
|
||||
typedef struct _GtkBindingArg GtkBindingArg;
|
||||
typedef struct _GtkBindingSignalSignal GtkBindingSignalSignal;
|
||||
typedef struct _GtkBindingSignalAction GtkBindingSignalAction;
|
||||
typedef struct _GtkBindingSignalCallback GtkBindingSignalCallback;
|
||||
|
||||
/**
|
||||
* GtkBindingSet:
|
||||
@@ -138,12 +141,17 @@ struct _GtkBindingArg
|
||||
} d;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_BINDING_SIGNAL,
|
||||
GTK_BINDING_ACTION,
|
||||
GTK_BINDING_CALLBACK
|
||||
} GtkBindingActionType;
|
||||
|
||||
/**
|
||||
* GtkBindingSignal:
|
||||
* @next: implementation detail
|
||||
* @signal_name: the action signal to be emitted
|
||||
* @n_args: number of arguments specified for the signal
|
||||
* @args: (array length=n_args): the arguments specified for the signal
|
||||
* @action_type: Actual type of the action
|
||||
*
|
||||
* A GtkBindingSignal stores the necessary information to
|
||||
* activate a widget in response to a key press via a signal
|
||||
@@ -151,12 +159,34 @@ struct _GtkBindingArg
|
||||
*/
|
||||
struct _GtkBindingSignal
|
||||
{
|
||||
GtkBindingSignal *next;
|
||||
gchar *signal_name;
|
||||
GtkBindingSignal *next;
|
||||
GtkBindingActionType action_type;
|
||||
};
|
||||
|
||||
struct _GtkBindingSignalSignal
|
||||
{
|
||||
GtkBindingSignal parent;
|
||||
const gchar *signal_name;
|
||||
guint n_args;
|
||||
GtkBindingArg *args;
|
||||
};
|
||||
|
||||
struct _GtkBindingSignalAction
|
||||
{
|
||||
GtkBindingSignal parent;
|
||||
const gchar *action_name;
|
||||
GVariant *variant;
|
||||
};
|
||||
|
||||
struct _GtkBindingSignalCallback
|
||||
{
|
||||
GtkBindingSignal parent;
|
||||
GtkBindingCallback callback;
|
||||
GVariant *args;
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_destroy;
|
||||
};
|
||||
|
||||
/* --- variables --- */
|
||||
static GHashTable *binding_entry_hash_table = NULL;
|
||||
static GSList *binding_key_hashes = NULL;
|
||||
@@ -168,31 +198,99 @@ static GQuark key_id_class_binding_set = 0;
|
||||
/* --- functions --- */
|
||||
|
||||
static GtkBindingSignal*
|
||||
binding_signal_new (const gchar *signal_name,
|
||||
guint n_args)
|
||||
binding_signal_new_signal (const gchar *signal_name,
|
||||
guint n_args)
|
||||
{
|
||||
GtkBindingSignal *signal;
|
||||
GtkBindingSignalSignal *signal;
|
||||
|
||||
signal = (GtkBindingSignal *) g_slice_alloc0 (sizeof (GtkBindingSignal) + n_args * sizeof (GtkBindingArg));
|
||||
signal->next = NULL;
|
||||
signal->signal_name = (gchar *)g_intern_string (signal_name);
|
||||
signal = (GtkBindingSignalSignal *) g_slice_alloc0 (sizeof (GtkBindingSignalSignal) + n_args * sizeof (GtkBindingArg));
|
||||
signal->parent.next = NULL;
|
||||
signal->parent.action_type = GTK_BINDING_SIGNAL;
|
||||
signal->signal_name = g_intern_string (signal_name);
|
||||
signal->n_args = n_args;
|
||||
signal->args = (GtkBindingArg *)(signal + 1);
|
||||
|
||||
return signal;
|
||||
return &signal->parent;
|
||||
}
|
||||
|
||||
static GtkBindingSignal*
|
||||
binding_signal_new_action (const gchar *action_name,
|
||||
GVariant *variant)
|
||||
{
|
||||
GtkBindingSignalAction *signal;
|
||||
|
||||
signal = g_slice_new0 (GtkBindingSignalAction);
|
||||
signal->parent.next = NULL;
|
||||
signal->parent.action_type = GTK_BINDING_ACTION;
|
||||
signal->action_name = g_intern_string (action_name);
|
||||
signal->variant = variant;
|
||||
if (variant)
|
||||
g_variant_ref_sink (variant);
|
||||
|
||||
return &signal->parent;
|
||||
}
|
||||
|
||||
static GtkBindingSignal *
|
||||
binding_signal_new_callback (GtkBindingCallback callback,
|
||||
GVariant *args,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy)
|
||||
{
|
||||
GtkBindingSignalCallback *signal;
|
||||
|
||||
signal = g_slice_new0 (GtkBindingSignalCallback);
|
||||
signal->parent.next = NULL;
|
||||
signal->parent.action_type = GTK_BINDING_CALLBACK;
|
||||
signal->callback = callback;
|
||||
signal->args = args;
|
||||
if (args)
|
||||
g_variant_ref_sink (args);
|
||||
signal->user_data = user_data;
|
||||
signal->user_destroy = user_destroy;
|
||||
|
||||
return &signal->parent;
|
||||
}
|
||||
|
||||
static void
|
||||
binding_signal_free (GtkBindingSignal *sig)
|
||||
binding_signal_free (GtkBindingSignal *signal)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < sig->n_args; i++)
|
||||
switch (signal->action_type)
|
||||
{
|
||||
if (G_TYPE_FUNDAMENTAL (sig->args[i].arg_type) == G_TYPE_STRING)
|
||||
g_free (sig->args[i].d.string_data);
|
||||
case GTK_BINDING_SIGNAL:
|
||||
{
|
||||
GtkBindingSignalSignal *sig = (GtkBindingSignalSignal *) signal;
|
||||
for (i = 0; i < sig->n_args; i++)
|
||||
{
|
||||
if (G_TYPE_FUNDAMENTAL (sig->args[i].arg_type) == G_TYPE_STRING)
|
||||
g_free (sig->args[i].d.string_data);
|
||||
}
|
||||
g_slice_free1 (sizeof (GtkBindingSignalSignal) + sig->n_args * sizeof (GtkBindingArg), sig);
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_BINDING_ACTION:
|
||||
{
|
||||
GtkBindingSignalAction *sig = (GtkBindingSignalAction *) signal;
|
||||
g_clear_pointer (&sig->variant, g_variant_unref);
|
||||
g_slice_free (GtkBindingSignalAction, sig);
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_BINDING_CALLBACK:
|
||||
{
|
||||
GtkBindingSignalCallback *sig = (GtkBindingSignalCallback *) signal;
|
||||
if (sig->user_destroy)
|
||||
sig->user_destroy (sig->user_data);
|
||||
g_slice_free (GtkBindingSignalCallback, sig);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
g_slice_free1 (sizeof (GtkBindingSignal) + sig->n_args * sizeof (GtkBindingArg), sig);
|
||||
}
|
||||
|
||||
static guint
|
||||
@@ -559,6 +657,114 @@ binding_compose_params (GObject *object,
|
||||
return valid;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
binding_signal_activate_signal (GtkBindingSignalSignal *sig,
|
||||
GObject *object)
|
||||
{
|
||||
GSignalQuery query;
|
||||
guint signal_id;
|
||||
GValue *params = NULL;
|
||||
GValue return_val = G_VALUE_INIT;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object));
|
||||
if (!signal_id)
|
||||
{
|
||||
g_warning ("gtk_binding_entry_activate(): "
|
||||
"could not find signal \"%s\" in the '%s' class ancestry",
|
||||
sig->signal_name,
|
||||
g_type_name (G_OBJECT_TYPE (object)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_signal_query (signal_id, &query);
|
||||
if (query.n_params != sig->n_args ||
|
||||
(query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
|
||||
!binding_compose_params (object, sig->args, &query, ¶ms))
|
||||
{
|
||||
g_warning ("gtk_binding_entry_activate(): "
|
||||
"signature mismatch for signal \"%s\" in the '%s' class ancestry",
|
||||
sig->signal_name,
|
||||
g_type_name (G_OBJECT_TYPE (object)));
|
||||
return FALSE;
|
||||
}
|
||||
else if (!(query.signal_flags & G_SIGNAL_ACTION))
|
||||
{
|
||||
g_warning ("gtk_binding_entry_activate(): "
|
||||
"signal \"%s\" in the '%s' class ancestry cannot be used for action emissions",
|
||||
sig->signal_name,
|
||||
g_type_name (G_OBJECT_TYPE (object)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (query.return_type == G_TYPE_BOOLEAN)
|
||||
g_value_init (&return_val, G_TYPE_BOOLEAN);
|
||||
|
||||
g_signal_emitv (params, signal_id, 0, &return_val);
|
||||
|
||||
if (query.return_type == G_TYPE_BOOLEAN)
|
||||
{
|
||||
if (g_value_get_boolean (&return_val))
|
||||
handled = TRUE;
|
||||
g_value_unset (&return_val);
|
||||
}
|
||||
else
|
||||
handled = TRUE;
|
||||
|
||||
if (params != NULL)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < query.n_params + 1; i++)
|
||||
g_value_unset (¶ms[i]);
|
||||
|
||||
g_free (params);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
binding_signal_activate_action (GtkBindingSignalAction *sig,
|
||||
GObject *object)
|
||||
{
|
||||
if (!GTK_IS_WIDGET (object))
|
||||
{
|
||||
g_warning ("gtk_binding_entry_activate(): "
|
||||
"actions must be emitted on GtkWidget subtypes, %s is not supported",
|
||||
G_OBJECT_TYPE_NAME (object));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gtk_widget_activate_action_variant (GTK_WIDGET (object), sig->action_name, sig->variant))
|
||||
{
|
||||
g_warning ("gtk_binding_entry_activate(): "
|
||||
"action \"%s\" does not exist on class \"%s\"",
|
||||
sig->action_name,
|
||||
G_OBJECT_TYPE_NAME (object));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
binding_signal_activate_callback (GtkBindingSignalCallback *sig,
|
||||
GObject *object)
|
||||
{
|
||||
if (!GTK_IS_WIDGET (object))
|
||||
{
|
||||
g_warning ("gtk_binding_entry_activate(): "
|
||||
"callbacks must be run on GtkWidget subtypes, %s is not supported",
|
||||
G_OBJECT_TYPE_NAME (object));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sig->callback (GTK_WIDGET (object), sig->args, sig->user_data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_binding_entry_activate (GtkBindingEntry *entry,
|
||||
GObject *object)
|
||||
@@ -566,7 +772,6 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
|
||||
GtkBindingSignal *sig;
|
||||
gboolean old_emission;
|
||||
gboolean handled = FALSE;
|
||||
gint i;
|
||||
|
||||
old_emission = entry->in_emission;
|
||||
entry->in_emission = TRUE;
|
||||
@@ -575,73 +780,23 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
|
||||
|
||||
for (sig = entry->signals; sig; sig = sig->next)
|
||||
{
|
||||
GSignalQuery query;
|
||||
guint signal_id;
|
||||
GValue *params = NULL;
|
||||
GValue return_val = G_VALUE_INIT;
|
||||
gchar *accelerator = NULL;
|
||||
|
||||
signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object));
|
||||
if (!signal_id)
|
||||
switch (sig->action_type)
|
||||
{
|
||||
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
|
||||
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
|
||||
"could not find signal \"%s\" in the '%s' class ancestry",
|
||||
entry->binding_set->set_name,
|
||||
accelerator,
|
||||
sig->signal_name,
|
||||
g_type_name (G_OBJECT_TYPE (object)));
|
||||
g_free (accelerator);
|
||||
continue;
|
||||
}
|
||||
case GTK_BINDING_SIGNAL:
|
||||
handled = binding_signal_activate_signal ((GtkBindingSignalSignal *) sig, object);
|
||||
break;
|
||||
|
||||
g_signal_query (signal_id, &query);
|
||||
if (query.n_params != sig->n_args ||
|
||||
(query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
|
||||
!binding_compose_params (object, sig->args, &query, ¶ms))
|
||||
{
|
||||
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
|
||||
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
|
||||
"signature mismatch for signal \"%s\" in the '%s' class ancestry",
|
||||
entry->binding_set->set_name,
|
||||
accelerator,
|
||||
sig->signal_name,
|
||||
g_type_name (G_OBJECT_TYPE (object)));
|
||||
}
|
||||
else if (!(query.signal_flags & G_SIGNAL_ACTION))
|
||||
{
|
||||
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
|
||||
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
|
||||
"signal \"%s\" in the '%s' class ancestry cannot be used for action emissions",
|
||||
entry->binding_set->set_name,
|
||||
accelerator,
|
||||
sig->signal_name,
|
||||
g_type_name (G_OBJECT_TYPE (object)));
|
||||
}
|
||||
g_free (accelerator);
|
||||
if (accelerator)
|
||||
continue;
|
||||
case GTK_BINDING_ACTION:
|
||||
handled = binding_signal_activate_action ((GtkBindingSignalAction *) sig, object);
|
||||
break;
|
||||
|
||||
if (query.return_type == G_TYPE_BOOLEAN)
|
||||
g_value_init (&return_val, G_TYPE_BOOLEAN);
|
||||
case GTK_BINDING_CALLBACK:
|
||||
handled = binding_signal_activate_callback ((GtkBindingSignalCallback *) sig, object);
|
||||
break;
|
||||
|
||||
g_signal_emitv (params, signal_id, 0, &return_val);
|
||||
|
||||
if (query.return_type == G_TYPE_BOOLEAN)
|
||||
{
|
||||
if (g_value_get_boolean (&return_val))
|
||||
handled = TRUE;
|
||||
g_value_unset (&return_val);
|
||||
}
|
||||
else
|
||||
handled = TRUE;
|
||||
|
||||
if (params != NULL)
|
||||
{
|
||||
for (i = 0; i < query.n_params + 1; i++)
|
||||
g_value_unset (¶ms[i]);
|
||||
|
||||
g_free (params);
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (entry->destroyed)
|
||||
@@ -858,6 +1013,30 @@ gtk_binding_entry_remove (GtkBindingSet *binding_set,
|
||||
binding_entry_destroy (entry);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_binding_entry_add_binding_signal (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
GtkBindingSignal *signal)
|
||||
{
|
||||
GtkBindingEntry *entry;
|
||||
GtkBindingSignal **signal_p;
|
||||
|
||||
keyval = gdk_keyval_to_lower (keyval);
|
||||
modifiers = modifiers & BINDING_MOD_MASK ();
|
||||
|
||||
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
|
||||
if (!entry)
|
||||
{
|
||||
gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
|
||||
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
|
||||
}
|
||||
signal_p = &entry->signals;
|
||||
while (*signal_p)
|
||||
signal_p = &(*signal_p)->next;
|
||||
*signal_p = signal;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_binding_entry_add_signall:
|
||||
* @binding_set: a #GtkBindingSet to add a signal to
|
||||
@@ -877,8 +1056,7 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
|
||||
const gchar *signal_name,
|
||||
GSList *binding_args)
|
||||
{
|
||||
GtkBindingEntry *entry;
|
||||
GtkBindingSignal *signal, **signal_p;
|
||||
GtkBindingSignal *signal;
|
||||
GSList *slist;
|
||||
guint n = 0;
|
||||
GtkBindingArg *arg;
|
||||
@@ -886,12 +1064,9 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
|
||||
g_return_if_fail (binding_set != NULL);
|
||||
g_return_if_fail (signal_name != NULL);
|
||||
|
||||
keyval = gdk_keyval_to_lower (keyval);
|
||||
modifiers = modifiers & BINDING_MOD_MASK ();
|
||||
signal = binding_signal_new_signal (signal_name, g_slist_length (binding_args));
|
||||
|
||||
signal = binding_signal_new (signal_name, g_slist_length (binding_args));
|
||||
|
||||
arg = signal->args;
|
||||
arg = ((GtkBindingSignalSignal *) signal)->args;
|
||||
for (slist = binding_args; slist; slist = slist->next)
|
||||
{
|
||||
GtkBindingArg *tmp_arg;
|
||||
@@ -933,16 +1108,7 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
|
||||
n++;
|
||||
}
|
||||
|
||||
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
|
||||
if (!entry)
|
||||
{
|
||||
gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
|
||||
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
|
||||
}
|
||||
signal_p = &entry->signals;
|
||||
while (*signal_p)
|
||||
signal_p = &(*signal_p)->next;
|
||||
*signal_p = signal;
|
||||
gtk_binding_entry_add_binding_signal (binding_set, keyval, modifiers, signal);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1060,6 +1226,97 @@ gtk_binding_entry_add_signal (GtkBindingSet *binding_set,
|
||||
g_slist_free (free_slist);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_binding_entry_add_action_variant:
|
||||
* @binding_set: a #GtkBindingSet to install an entry for
|
||||
* @keyval: key value of binding to install
|
||||
* @modifiers: key modifier of binding to install
|
||||
* @action_name: signal to execute upon activation
|
||||
* @args: #GVariant of the arguments or %NULL if none
|
||||
*
|
||||
* Override or install a new key binding for @keyval with @modifiers on
|
||||
* @binding_set. When the binding is activated, @action_name will be
|
||||
* activated on the target widget, with @args used as arguments.
|
||||
*/
|
||||
void
|
||||
gtk_binding_entry_add_action_variant (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const gchar *action_name,
|
||||
GVariant *args)
|
||||
{
|
||||
g_return_if_fail (binding_set != NULL);
|
||||
g_return_if_fail (action_name != NULL);
|
||||
|
||||
gtk_binding_entry_add_binding_signal (binding_set,
|
||||
keyval,
|
||||
modifiers,
|
||||
binding_signal_new_action (action_name, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_binding_entry_add_action:
|
||||
* @binding_set: a #GtkBindingSet to install an entry for
|
||||
* @keyval: key value of binding to install
|
||||
* @modifiers: key modifier of binding to install
|
||||
* @action_name: signal to execute upon activation
|
||||
* @format_string: GVariant format string for arguments or %NULL
|
||||
* for no arguments
|
||||
* @...: arguments, as given by format string
|
||||
*
|
||||
* Override or install a new key binding for @keyval with @modifiers on
|
||||
* @binding_set. When the binding is activated, @action_name will be
|
||||
* activated on the target widget, with arguments read according to
|
||||
* @format_string.
|
||||
*/
|
||||
void
|
||||
gtk_binding_entry_add_action (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const char *action_name,
|
||||
const char *format_string,
|
||||
...)
|
||||
{
|
||||
GVariant *parameters = NULL;
|
||||
|
||||
g_return_if_fail (binding_set != NULL);
|
||||
g_return_if_fail (action_name != NULL);
|
||||
|
||||
if (format_string != NULL)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, format_string);
|
||||
parameters = g_variant_new_va (format_string, NULL, &args);
|
||||
va_end (args);
|
||||
|
||||
g_variant_ref_sink (parameters);
|
||||
}
|
||||
|
||||
gtk_binding_entry_add_action_variant (binding_set, keyval, modifiers, action_name, parameters);
|
||||
|
||||
g_clear_pointer (¶meters, g_variant_unref);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_binding_entry_add_callback (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
GtkBindingCallback callback,
|
||||
GVariant *args,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy)
|
||||
{
|
||||
g_return_if_fail (binding_set != NULL);
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
gtk_binding_entry_add_binding_signal (binding_set,
|
||||
keyval,
|
||||
modifiers,
|
||||
binding_signal_new_callback (callback, args, user_data, user_destroy));
|
||||
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_binding_parse_signal (GScanner *scanner,
|
||||
GtkBindingSet *binding_set,
|
||||
|
||||
@@ -35,11 +35,25 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
#include <gtk/gtktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkBindingSet GtkBindingSet;
|
||||
|
||||
/**
|
||||
* GtkBindingCallback:
|
||||
* @widget: The object to invoke the callback on
|
||||
* @args: (allow-none): The arguments or %NULL if none
|
||||
* @user_data: The user data passed when registering the callback
|
||||
*
|
||||
* Prototype of the callback function registered with
|
||||
* gtk_binding_entry_add_callback.
|
||||
*/
|
||||
typedef void (* GtkBindingCallback) (GtkWidget *widget,
|
||||
GVariant *args,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkBindingSet *gtk_binding_set_new (const gchar *set_name);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -76,6 +90,29 @@ GDK_AVAILABLE_IN_ALL
|
||||
GTokenType gtk_binding_entry_add_signal_from_string
|
||||
(GtkBindingSet *binding_set,
|
||||
const gchar *signal_desc);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_binding_entry_add_action_variant
|
||||
(GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const char *action_name,
|
||||
GVariant *args);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_binding_entry_add_action (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const char *action_name,
|
||||
const char *format_string,
|
||||
...);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_binding_entry_add_callback(GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
GtkBindingCallback callback,
|
||||
GVariant *args,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_binding_entry_remove (GtkBindingSet *binding_set,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "gtkbookmarksmanager.h"
|
||||
#include "gtkbookmarksmanagerprivate.h"
|
||||
#include "gtkfilechooser.h" /* for the GError types */
|
||||
|
||||
static void
|
||||
@@ -539,7 +539,7 @@ _gtk_bookmarks_manager_set_bookmark_label (GtkBookmarksManager *manager,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
static gboolean
|
||||
_gtk_bookmarks_manager_get_xdg_type (GtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
GUserDirectory *directory)
|
||||
|
||||
@@ -79,9 +79,6 @@ gboolean _gtk_bookmarks_manager_set_bookmark_label (GtkBookmarksManager *manager
|
||||
const gchar *label,
|
||||
GError **error);
|
||||
|
||||
gboolean _gtk_bookmarks_manager_get_xdg_type (GtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
GUserDirectory *directory);
|
||||
gboolean _gtk_bookmarks_manager_get_is_builtin (GtkBookmarksManager *manager,
|
||||
GFile *file);
|
||||
|
||||
+10
-4
@@ -550,7 +550,7 @@ gtk_box_forall (GtkContainer *container,
|
||||
* @sibling: (nullable): the sibling to move @child after, or %NULL
|
||||
*
|
||||
* Inserts @child in the position after @sibling in the list
|
||||
* of @box children. If @sibling is %NULL, insert @child at
|
||||
* of @box children. If @sibling is %NULL, insert @child at
|
||||
* the first position.
|
||||
*/
|
||||
void
|
||||
@@ -558,11 +558,14 @@ gtk_box_insert_child_after (GtkBox *box,
|
||||
GtkWidget *child,
|
||||
GtkWidget *sibling)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (box);
|
||||
GtkWidget *widget;
|
||||
|
||||
g_return_if_fail (GTK_IS_BOX (box));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (gtk_widget_get_parent (child) == NULL);
|
||||
|
||||
widget = GTK_WIDGET (box);
|
||||
|
||||
if (sibling)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (sibling));
|
||||
@@ -593,11 +596,14 @@ gtk_box_reorder_child_after (GtkBox *box,
|
||||
GtkWidget *child,
|
||||
GtkWidget *sibling)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (box);
|
||||
GtkWidget *widget;
|
||||
|
||||
g_return_if_fail (GTK_IS_BOX (box));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
g_return_if_fail (gtk_widget_get_parent (child) == widget);
|
||||
g_return_if_fail (gtk_widget_get_parent (child) == (GtkWidget *)box);
|
||||
|
||||
widget = GTK_WIDGET (box);
|
||||
|
||||
if (sibling)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_WIDGET (sibling));
|
||||
|
||||
+6
-6
@@ -230,12 +230,12 @@ gtk_buildable_construct_child (GtkBuildable *buildable,
|
||||
* if it doesn't.
|
||||
**/
|
||||
gboolean
|
||||
gtk_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GMarkupParser *parser,
|
||||
gpointer *data)
|
||||
gtk_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GtkBuildableParser *parser,
|
||||
gpointer *data)
|
||||
{
|
||||
GtkBuildableIface *iface;
|
||||
|
||||
|
||||
+88
-37
@@ -33,10 +33,46 @@ G_BEGIN_DECLS
|
||||
#define GTK_IS_BUILDABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_BUILDABLE))
|
||||
#define GTK_BUILDABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_BUILDABLE, GtkBuildableIface))
|
||||
|
||||
|
||||
typedef struct _GtkBuildable GtkBuildable; /* Dummy typedef */
|
||||
typedef struct _GtkBuildableIface GtkBuildableIface;
|
||||
|
||||
typedef struct _GtkBuildableParseContext GtkBuildableParseContext;
|
||||
typedef struct _GtkBuildableParser GtkBuildableParser;
|
||||
|
||||
struct _GtkBuildableParser
|
||||
{
|
||||
/* Called for open tags <foo bar="baz"> */
|
||||
void (*start_element) (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
/* Called for close tags </foo> */
|
||||
void (*end_element) (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
/* Called for character data */
|
||||
/* text is not nul-terminated */
|
||||
void (*text) (GtkBuildableParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
/* Called on error, including one set by other
|
||||
* methods in the vtable. The GError should not be freed.
|
||||
*/
|
||||
void (*error) (GtkBuildableParseContext *context,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkBuildableIface:
|
||||
* @g_iface: the parent class
|
||||
@@ -90,42 +126,42 @@ struct _GtkBuildableIface
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/* virtual table */
|
||||
void (* set_name) (GtkBuildable *buildable,
|
||||
const gchar *name);
|
||||
const gchar * (* get_name) (GtkBuildable *buildable);
|
||||
void (* add_child) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *type);
|
||||
void (* set_buildable_property) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *name,
|
||||
const GValue *value);
|
||||
GObject * (* construct_child) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *name);
|
||||
gboolean (* custom_tag_start) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GMarkupParser *parser,
|
||||
gpointer *data);
|
||||
void (* custom_tag_end) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
gpointer data);
|
||||
void (* custom_finished) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
gpointer data);
|
||||
void (* parser_finished) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder);
|
||||
void (* set_name) (GtkBuildable *buildable,
|
||||
const gchar *name);
|
||||
const gchar * (* get_name) (GtkBuildable *buildable);
|
||||
void (* add_child) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *type);
|
||||
void (* set_buildable_property) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *name,
|
||||
const GValue *value);
|
||||
GObject * (* construct_child) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *name);
|
||||
gboolean (* custom_tag_start) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GtkBuildableParser *parser,
|
||||
gpointer *data);
|
||||
void (* custom_tag_end) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
gpointer data);
|
||||
void (* custom_finished) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
gpointer data);
|
||||
void (* parser_finished) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder);
|
||||
|
||||
GObject * (* get_internal_child) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *childname);
|
||||
GObject * (* get_internal_child) (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *childname);
|
||||
};
|
||||
|
||||
|
||||
@@ -156,7 +192,7 @@ gboolean gtk_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
GObject *child,
|
||||
const gchar *tagname,
|
||||
GMarkupParser *parser,
|
||||
GtkBuildableParser *parser,
|
||||
gpointer *data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_buildable_custom_tag_end (GtkBuildable *buildable,
|
||||
@@ -178,6 +214,21 @@ GObject * gtk_buildable_get_internal_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
const gchar *childname);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_buildable_parse_context_push (GtkBuildableParseContext *context,
|
||||
const GtkBuildableParser *parser,
|
||||
gpointer user_data);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gpointer gtk_buildable_parse_context_pop (GtkBuildableParseContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gtk_buildable_parse_context_get_element (GtkBuildableParseContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GPtrArray *gtk_buildable_parse_context_get_element_stack (GtkBuildableParseContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_buildable_parse_context_get_position (GtkBuildableParseContext *context,
|
||||
gint *line_number,
|
||||
gint *char_number);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_BUILDABLE_H__ */
|
||||
|
||||
+27
-27
@@ -80,12 +80,12 @@ gtk_builder_menu_pop_frame (GtkBuilderMenuState *state)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_builder_menu_start_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
gtk_builder_menu_start_element (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderMenuState *state = user_data;
|
||||
|
||||
@@ -214,14 +214,15 @@ gtk_builder_menu_start_element (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
{
|
||||
const GSList *element_stack;
|
||||
GPtrArray *element_stack;
|
||||
|
||||
element_stack = g_markup_parse_context_get_element_stack (context);
|
||||
element_stack = gtk_buildable_parse_context_get_element_stack (context);
|
||||
|
||||
if (element_stack->next)
|
||||
if (element_stack->len > 1)
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
||||
_("Element <%s> not allowed inside <%s>"),
|
||||
element_name, (const gchar *) element_stack->next->data);
|
||||
element_name,
|
||||
(const gchar *) g_ptr_array_index (element_stack, element_stack->len - 2));
|
||||
|
||||
else
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
||||
@@ -230,10 +231,10 @@ gtk_builder_menu_start_element (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_builder_menu_end_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
gtk_builder_menu_end_element (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderMenuState *state = user_data;
|
||||
|
||||
@@ -297,11 +298,11 @@ gtk_builder_menu_end_element (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_builder_menu_text (GMarkupParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
gtk_builder_menu_text (GtkBuildableParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderMenuState *state = user_data;
|
||||
gint i;
|
||||
@@ -315,15 +316,15 @@ gtk_builder_menu_text (GMarkupParseContext *context,
|
||||
else
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
_("Text may not appear inside <%s>"),
|
||||
g_markup_parse_context_get_element (context));
|
||||
gtk_buildable_parse_context_get_element (context));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_builder_menu_error (GMarkupParseContext *context,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
gtk_builder_menu_error (GtkBuildableParseContext *context,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkBuilderMenuState *state = user_data;
|
||||
|
||||
@@ -348,12 +349,11 @@ gtk_builder_menu_error (GMarkupParseContext *context,
|
||||
g_slice_free (GtkBuilderMenuState, state);
|
||||
}
|
||||
|
||||
static GMarkupParser gtk_builder_menu_subparser =
|
||||
static GtkBuildableParser gtk_builder_menu_subparser =
|
||||
{
|
||||
gtk_builder_menu_start_element,
|
||||
gtk_builder_menu_end_element,
|
||||
gtk_builder_menu_text,
|
||||
NULL, /* passthrough */
|
||||
gtk_builder_menu_error
|
||||
};
|
||||
|
||||
@@ -369,7 +369,7 @@ _gtk_builder_menu_start (ParserData *parser_data,
|
||||
|
||||
state = g_slice_new0 (GtkBuilderMenuState);
|
||||
state->parser_data = parser_data;
|
||||
g_markup_parse_context_push (parser_data->ctx, >k_builder_menu_subparser, state);
|
||||
gtk_buildable_parse_context_push (&parser_data->ctx, >k_builder_menu_subparser, state);
|
||||
|
||||
if (COLLECT (STRING, "id", &id))
|
||||
{
|
||||
@@ -387,7 +387,7 @@ _gtk_builder_menu_end (ParserData *parser_data)
|
||||
{
|
||||
GtkBuilderMenuState *state;
|
||||
|
||||
state = g_markup_parse_context_pop (parser_data->ctx);
|
||||
state = gtk_buildable_parse_context_pop (&parser_data->ctx);
|
||||
gtk_builder_menu_pop_frame (state);
|
||||
|
||||
g_assert (state->frame.prev == NULL);
|
||||
|
||||
+33
-26
@@ -134,7 +134,7 @@
|
||||
* "bind-source" to specify the source object of the binding, and
|
||||
* optionally, "bind-property" and "bind-flags" to specify the
|
||||
* source property and source binding flags respectively.
|
||||
* Internally builder implement this using GBinding objects.
|
||||
* Internally builder implements this using GBinding objects.
|
||||
* For more information see g_object_bind_property()
|
||||
*
|
||||
* Signal handlers are set up with the <signal> element. The “name”
|
||||
@@ -153,7 +153,7 @@
|
||||
* been constructed by GTK+ as part of a composite widget, to set
|
||||
* properties on them or to add further children (e.g. the @vbox of
|
||||
* a #GtkDialog). This can be achieved by setting the “internal-child”
|
||||
* propery of the <child> element to a true value. Note that GtkBuilder
|
||||
* property of the <child> element to a true value. Note that GtkBuilder
|
||||
* still requires an <object> element for the internal child, even if it
|
||||
* has already been constructed.
|
||||
*
|
||||
@@ -2095,6 +2095,10 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
|
||||
gchar **vector = g_strsplit (string, "\n", 0);
|
||||
g_value_take_boxed (value, vector);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, G_TYPE_BYTES))
|
||||
{
|
||||
g_value_take_boxed (value, g_bytes_new (string, strlen (string)));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error,
|
||||
@@ -2108,7 +2112,7 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
|
||||
case G_TYPE_OBJECT:
|
||||
case G_TYPE_INTERFACE:
|
||||
if (G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF) ||
|
||||
G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE) ||
|
||||
G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE) ||
|
||||
G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE))
|
||||
{
|
||||
gchar *filename;
|
||||
@@ -2156,6 +2160,7 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
|
||||
if (pixbuf == NULL)
|
||||
{
|
||||
GtkIconTheme *theme;
|
||||
GdkPaintable *texture;
|
||||
|
||||
g_warning ("Could not load image '%s': %s",
|
||||
string, tmp_error->message);
|
||||
@@ -2163,11 +2168,13 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
|
||||
|
||||
/* fall back to a missing image */
|
||||
theme = gtk_icon_theme_get_default ();
|
||||
pixbuf = gtk_icon_theme_load_icon (theme,
|
||||
texture = gtk_icon_theme_load_icon (theme,
|
||||
"image-missing",
|
||||
16,
|
||||
GTK_ICON_LOOKUP_USE_BUILTIN,
|
||||
NULL);
|
||||
pixbuf = gdk_pixbuf_get_from_texture (GDK_TEXTURE (texture));
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
if (pixbuf)
|
||||
@@ -2802,7 +2809,7 @@ gtk_builder_get_application (GtkBuilder *builder)
|
||||
/*< private >
|
||||
* _gtk_builder_prefix_error:
|
||||
* @builder: a #GtkBuilder
|
||||
* @context: the #GMarkupParseContext
|
||||
* @context: the #GtkBuildableParseContext
|
||||
* @error: an error
|
||||
*
|
||||
* Calls g_prefix_error() to prepend a filename:line:column marker
|
||||
@@ -2814,21 +2821,21 @@ gtk_builder_get_application (GtkBuilder *builder)
|
||||
* g_markup_collect_attributes() in a start_element vfunc.
|
||||
*/
|
||||
void
|
||||
_gtk_builder_prefix_error (GtkBuilder *builder,
|
||||
GMarkupParseContext *context,
|
||||
GError **error)
|
||||
_gtk_builder_prefix_error (GtkBuilder *builder,
|
||||
GtkBuildableParseContext *context,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
gint line, col;
|
||||
|
||||
g_markup_parse_context_get_position (context, &line, &col);
|
||||
gtk_buildable_parse_context_get_position (context, &line, &col);
|
||||
g_prefix_error (error, "%s:%d:%d ", priv->filename, line, col);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _gtk_builder_error_unhandled_tag:
|
||||
* @builder: a #GtkBuilder
|
||||
* @context: the #GMarkupParseContext
|
||||
* @context: the #GtkBuildableParseContext
|
||||
* @object: name of the object that is being handled
|
||||
* @element_name: name of the element whose start tag is being handled
|
||||
* @error: return location for the error
|
||||
@@ -2839,16 +2846,16 @@ _gtk_builder_prefix_error (GtkBuilder *builder,
|
||||
* This is intended to be called in a start_element vfunc.
|
||||
*/
|
||||
void
|
||||
_gtk_builder_error_unhandled_tag (GtkBuilder *builder,
|
||||
GMarkupParseContext *context,
|
||||
const gchar *object,
|
||||
const gchar *element_name,
|
||||
GError **error)
|
||||
_gtk_builder_error_unhandled_tag (GtkBuilder *builder,
|
||||
GtkBuildableParseContext *context,
|
||||
const gchar *object,
|
||||
const gchar *element_name,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
gint line, col;
|
||||
|
||||
g_markup_parse_context_get_position (context, &line, &col);
|
||||
gtk_buildable_parse_context_get_position (context, &line, &col);
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_UNHANDLED_TAG,
|
||||
@@ -2859,7 +2866,7 @@ _gtk_builder_error_unhandled_tag (GtkBuilder *builder,
|
||||
|
||||
/*< private >
|
||||
* @builder: a #GtkBuilder
|
||||
* @context: the #GMarkupParseContext
|
||||
* @context: the #GtkBuildableParseContext
|
||||
* @parent_name: the name of the expected parent element
|
||||
* @error: return location for an error
|
||||
*
|
||||
@@ -2872,27 +2879,27 @@ _gtk_builder_error_unhandled_tag (GtkBuilder *builder,
|
||||
* Returns: %TRUE if @parent_name is the parent element
|
||||
*/
|
||||
gboolean
|
||||
_gtk_builder_check_parent (GtkBuilder *builder,
|
||||
GMarkupParseContext *context,
|
||||
const gchar *parent_name,
|
||||
GError **error)
|
||||
_gtk_builder_check_parent (GtkBuilder *builder,
|
||||
GtkBuildableParseContext *context,
|
||||
const gchar *parent_name,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
const GSList *stack;
|
||||
GPtrArray *stack;
|
||||
gint line, col;
|
||||
const gchar *parent;
|
||||
const gchar *element;
|
||||
|
||||
stack = g_markup_parse_context_get_element_stack (context);
|
||||
stack = gtk_buildable_parse_context_get_element_stack (context);
|
||||
|
||||
element = (const gchar *)stack->data;
|
||||
parent = stack->next ? (const gchar *)stack->next->data : "";
|
||||
element = g_ptr_array_index (stack, stack->len - 1);
|
||||
parent = stack->len > 1 ? g_ptr_array_index (stack, stack->len - 2) : "";
|
||||
|
||||
if (g_str_equal (parent_name, parent) ||
|
||||
(g_str_equal (parent_name, "object") && g_str_equal (parent, "template")))
|
||||
return TRUE;
|
||||
|
||||
g_markup_parse_context_get_position (context, &line, &col);
|
||||
gtk_buildable_parse_context_get_position (context, &line, &col);
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_TAG,
|
||||
|
||||
+394
-70
@@ -31,6 +31,332 @@
|
||||
#include "gtkintl.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
const GtkBuildableParser *last_parser;
|
||||
gpointer last_user_data;
|
||||
int last_depth;
|
||||
} GtkBuildableParserStack;
|
||||
|
||||
static void
|
||||
pop_subparser_stack (GtkBuildableParseContext *context)
|
||||
{
|
||||
GtkBuildableParserStack *stack =
|
||||
&g_array_index (context->subparser_stack, GtkBuildableParserStack,
|
||||
context->subparser_stack->len - 1);
|
||||
|
||||
context->awaiting_pop = TRUE;
|
||||
context->held_user_data = context->user_data;
|
||||
|
||||
context->user_data = stack->last_user_data;
|
||||
context->parser = stack->last_parser;
|
||||
|
||||
g_array_set_size (context->subparser_stack, context->subparser_stack->len - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
possibly_finish_subparser (GtkBuildableParseContext *context)
|
||||
{
|
||||
if (context->subparser_stack->len > 0)
|
||||
{
|
||||
GtkBuildableParserStack *stack =
|
||||
&g_array_index (context->subparser_stack, GtkBuildableParserStack,
|
||||
context->subparser_stack->len - 1);
|
||||
|
||||
if (stack->last_depth == context->tag_stack->len)
|
||||
pop_subparser_stack (context);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_start_element (GMarkupParseContext *gm_context,
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuildableParseContext *context = user_data;
|
||||
|
||||
// Due to the way GMarkup works we're sure this will live until the end_element callback
|
||||
g_ptr_array_add (context->tag_stack, (char *)element_name);
|
||||
|
||||
if (context->parser->start_element)
|
||||
context->parser->start_element (context, element_name,
|
||||
attribute_names, attribute_values,
|
||||
context->user_data, error);
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_end_element (GMarkupParseContext *gm_context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuildableParseContext *context = user_data;
|
||||
|
||||
possibly_finish_subparser (context);
|
||||
|
||||
if (context->parser->end_element)
|
||||
context->parser->end_element (context, element_name, context->user_data, error);
|
||||
|
||||
g_ptr_array_set_size (context->tag_stack, context->tag_stack->len - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_text (GMarkupParseContext *gm_context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuildableParseContext *context = user_data;
|
||||
|
||||
if (context->parser->text)
|
||||
context->parser->text (context, text, text_len, context->user_data, error);
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_error (GMarkupParseContext *gm_context,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkBuildableParseContext *context = user_data;
|
||||
|
||||
if (context->parser->error)
|
||||
context->parser->error (context, error, context->user_data);
|
||||
|
||||
/* report the error all the way up to free all the user-data */
|
||||
|
||||
while (context->subparser_stack->len > 0)
|
||||
{
|
||||
pop_subparser_stack (context);
|
||||
context->awaiting_pop = FALSE; /* already been freed */
|
||||
|
||||
if (context->parser->error)
|
||||
context->parser->error (context, error, context->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
static const GMarkupParser gmarkup_parser = {
|
||||
proxy_start_element,
|
||||
proxy_end_element,
|
||||
proxy_text,
|
||||
NULL,
|
||||
proxy_error,
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_buildable_parse_context_init (GtkBuildableParseContext *context,
|
||||
const GtkBuildableParser *parser,
|
||||
gpointer user_data)
|
||||
{
|
||||
context->internal_callbacks = &gmarkup_parser;
|
||||
context->ctx = NULL;
|
||||
|
||||
context->parser = parser;
|
||||
context->user_data = user_data;
|
||||
|
||||
context->subparser_stack = g_array_new (FALSE, FALSE, sizeof (GtkBuildableParserStack));
|
||||
context->tag_stack = g_ptr_array_new ();
|
||||
context->held_user_data = NULL;
|
||||
context->awaiting_pop = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_buildable_parse_context_free (GtkBuildableParseContext *context)
|
||||
{
|
||||
g_array_unref (context->subparser_stack);
|
||||
g_ptr_array_unref (context->tag_stack);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_buildable_parse_context_parse (GtkBuildableParseContext *context,
|
||||
const gchar *text,
|
||||
gssize text_len,
|
||||
GError **error)
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
if (_gtk_buildable_parser_is_precompiled (text, text_len))
|
||||
{
|
||||
res = _gtk_buildable_parser_replay_precompiled (context, text, text_len, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->ctx = g_markup_parse_context_new (context->internal_callbacks,
|
||||
G_MARKUP_TREAT_CDATA_AS_TEXT,
|
||||
context, NULL);
|
||||
res = g_markup_parse_context_parse (context->ctx, text, text_len, error);
|
||||
g_markup_parse_context_free (context->ctx);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_buildable_parse_context_push:
|
||||
* @context: a #GtkBuildableParseContext
|
||||
* @parser: a #GtkBuildableParser
|
||||
* @user_data: user data to pass to #GtkBuildableParser functions
|
||||
*
|
||||
* Temporarily redirects markup data to a sub-parser.
|
||||
*
|
||||
* This function may only be called from the start_element handler of
|
||||
* a #GtkBuildableParser. It must be matched with a corresponding call to
|
||||
* gtk_buildable_parse_context_pop() in the matching end_element handler
|
||||
* (except in the case that the parser aborts due to an error).
|
||||
*
|
||||
* All tags, text and other data between the matching tags is
|
||||
* redirected to the subparser given by @parser. @user_data is used
|
||||
* as the user_data for that parser. @user_data is also passed to the
|
||||
* error callback in the event that an error occurs. This includes
|
||||
* errors that occur in subparsers of the subparser.
|
||||
*
|
||||
* The end tag matching the start tag for which this call was made is
|
||||
* handled by the previous parser (which is given its own user_data)
|
||||
* which is why gtk_buildable_parse_context_pop() is provided to allow "one
|
||||
* last access" to the @user_data provided to this function. In the
|
||||
* case of error, the @user_data provided here is passed directly to
|
||||
* the error callback of the subparser and gtk_buildable_parse_context_pop()
|
||||
* should not be called. In either case, if @user_data was allocated
|
||||
* then it ought to be freed from both of these locations.
|
||||
*
|
||||
* This function is not intended to be directly called by users
|
||||
* interested in invoking subparsers. Instead, it is intended to be
|
||||
* used by the subparsers themselves to implement a higher-level
|
||||
* interface.
|
||||
*
|
||||
* For an example of how to use this, see g_markup_parse_context_push() which
|
||||
* has the same kind of API.
|
||||
**/
|
||||
void
|
||||
gtk_buildable_parse_context_push (GtkBuildableParseContext *context,
|
||||
const GtkBuildableParser *parser,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkBuildableParserStack stack = { 0 };
|
||||
|
||||
stack.last_parser = context->parser;
|
||||
stack.last_user_data = context->user_data;
|
||||
stack.last_depth = context->tag_stack->len; // If at end_element time we're this deep, then pop it
|
||||
|
||||
context->parser = parser;
|
||||
context->user_data = user_data;
|
||||
|
||||
g_array_append_val (context->subparser_stack, stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_buildable_parse_context_pop:
|
||||
* @context: a #GtkBuildableParseContext
|
||||
*
|
||||
* Completes the process of a temporary sub-parser redirection.
|
||||
*
|
||||
* This function exists to collect the user_data allocated by a
|
||||
* matching call to gtk_buildable_parse_context_push(). It must be called
|
||||
* in the end_element handler corresponding to the start_element
|
||||
* handler during which gtk_buildable_parse_context_push() was called.
|
||||
* You must not call this function from the error callback -- the
|
||||
* @user_data is provided directly to the callback in that case.
|
||||
*
|
||||
* This function is not intended to be directly called by users
|
||||
* interested in invoking subparsers. Instead, it is intended to
|
||||
* be used by the subparsers themselves to implement a higher-level
|
||||
* interface.
|
||||
*
|
||||
* Returns: the user data passed to gtk_buildable_parse_context_push()
|
||||
*/
|
||||
gpointer
|
||||
gtk_buildable_parse_context_pop (GtkBuildableParseContext *context)
|
||||
{
|
||||
gpointer user_data;
|
||||
|
||||
if (!context->awaiting_pop)
|
||||
possibly_finish_subparser (context);
|
||||
|
||||
g_assert (context->awaiting_pop);
|
||||
|
||||
context->awaiting_pop = FALSE;
|
||||
|
||||
user_data = context->held_user_data;
|
||||
context->held_user_data = NULL;
|
||||
|
||||
return user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_buildable_parse_context_get_element:
|
||||
* @context: a #GtkBuildablParseContext
|
||||
*
|
||||
* Retrieves the name of the currently open element.
|
||||
*
|
||||
* If called from the start_element or end_element handlers this will
|
||||
* give the element_name as passed to those functions. For the parent
|
||||
* elements, see gtk_buildable_parse_context_get_element_stack().
|
||||
*
|
||||
* Returns: the name of the currently open element, or %NULL
|
||||
*/
|
||||
const char *
|
||||
gtk_buildable_parse_context_get_element (GtkBuildableParseContext *context)
|
||||
{
|
||||
if (context->tag_stack->len > 0)
|
||||
return g_ptr_array_index (context->tag_stack, context->tag_stack->len - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_buildable_parse_context_get_element_stack:
|
||||
* @context: a #GtkBuildableParseContext
|
||||
*
|
||||
* Retrieves the element stack from the internal state of the parser.
|
||||
*
|
||||
* The returned #GPtrArray is an array of strings where the last item is
|
||||
* the currently open tag (as would be returned by
|
||||
* gtk_buildable_parse_context_get_element()) and the previous item is its
|
||||
* immediate parent.
|
||||
*
|
||||
* This function is intended to be used in the start_element and
|
||||
* end_element handlers where gtk_buildable_parse_context_get_element()
|
||||
* would merely return the name of the element that is being
|
||||
* processed.
|
||||
*
|
||||
* Returns: (transfer none) (element-type utf8): the element stack, which must not be modified
|
||||
*/
|
||||
GPtrArray *
|
||||
gtk_buildable_parse_context_get_element_stack (GtkBuildableParseContext *context)
|
||||
{
|
||||
return context->tag_stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_buildable_parse_context_get_position:
|
||||
* @context: a #GtkBuildableParseContext
|
||||
* @line_number: (out) (optional): return location for a line number, or %NULL
|
||||
* @char_number: (out) (optional): return location for a char-on-line number, or %NULL
|
||||
*
|
||||
* Retrieves the current line number and the number of the character on
|
||||
* that line. Intended for use in error messages; there are no strict
|
||||
* semantics for what constitutes the "current" line number other than
|
||||
* "the best number we could come up with for error messages."
|
||||
*/
|
||||
void
|
||||
gtk_buildable_parse_context_get_position (GtkBuildableParseContext *context,
|
||||
gint *line_number,
|
||||
gint *char_number)
|
||||
|
||||
{
|
||||
if (context->ctx)
|
||||
g_markup_parse_context_get_position (context->ctx, line_number, char_number);
|
||||
else
|
||||
{
|
||||
if (line_number)
|
||||
*line_number = 0;
|
||||
if (char_number)
|
||||
*char_number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void free_property_info (PropertyInfo *info);
|
||||
static void free_object_info (ObjectInfo *info);
|
||||
|
||||
@@ -73,7 +399,7 @@ error_missing_attribute (ParserData *data,
|
||||
{
|
||||
gint line, col;
|
||||
|
||||
g_markup_parse_context_get_position (data->ctx, &line, &col);
|
||||
gtk_buildable_parse_context_get_position (&data->ctx, &line, &col);
|
||||
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
@@ -90,7 +416,7 @@ error_invalid_tag (ParserData *data,
|
||||
{
|
||||
gint line, col;
|
||||
|
||||
g_markup_parse_context_get_position (data->ctx, &line, &col);
|
||||
gtk_buildable_parse_context_get_position (&data->ctx, &line, &col);
|
||||
|
||||
if (expected)
|
||||
g_set_error (error,
|
||||
@@ -113,7 +439,7 @@ error_unhandled_tag (ParserData *data,
|
||||
{
|
||||
gint line, col;
|
||||
|
||||
g_markup_parse_context_get_position (data->ctx, &line, &col);
|
||||
gtk_buildable_parse_context_get_position (&data->ctx, &line, &col);
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_UNHANDLED_TAG,
|
||||
@@ -193,7 +519,7 @@ parse_requires (ParserData *data,
|
||||
G_MARKUP_COLLECT_STRING, "version", &version,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,7 +529,7 @@ parse_requires (ParserData *data,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_VALUE,
|
||||
"'version' attribute has malformed value '%s'", version);
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
version_major = g_ascii_strtoll (split[0], NULL, 10);
|
||||
@@ -234,12 +560,12 @@ is_requested_object (const gchar *object,
|
||||
}
|
||||
|
||||
static void
|
||||
parse_object (GMarkupParseContext *context,
|
||||
ParserData *data,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
GError **error)
|
||||
parse_object (GtkBuildableParseContext *context,
|
||||
ParserData *data,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
GError **error)
|
||||
{
|
||||
ObjectInfo *object_info;
|
||||
ChildInfo* child_info;
|
||||
@@ -271,7 +597,7 @@ parse_object (GMarkupParseContext *context,
|
||||
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "id", &object_id,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,17 +688,17 @@ parse_object (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
g_markup_parse_context_get_position (context, &line, NULL);
|
||||
gtk_buildable_parse_context_get_position (context, &line, NULL);
|
||||
g_hash_table_insert (data->object_ids, g_strdup (object_id), GINT_TO_POINTER (line));
|
||||
}
|
||||
|
||||
static void
|
||||
parse_template (GMarkupParseContext *context,
|
||||
ParserData *data,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
GError **error)
|
||||
parse_template (GtkBuildableParseContext *context,
|
||||
ParserData *data,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
GError **error)
|
||||
{
|
||||
ObjectInfo *object_info;
|
||||
const gchar *object_class = NULL;
|
||||
@@ -388,7 +714,7 @@ parse_template (GMarkupParseContext *context,
|
||||
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "parent", &parent_class,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -466,7 +792,7 @@ parse_template (GMarkupParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
g_markup_parse_context_get_position (context, &line, NULL);
|
||||
gtk_buildable_parse_context_get_position (context, &line, NULL);
|
||||
g_hash_table_insert (data->object_ids, g_strdup (object_class), GINT_TO_POINTER (line));
|
||||
}
|
||||
|
||||
@@ -510,7 +836,7 @@ parse_child (ParserData *data,
|
||||
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "internal-child", &internal_child,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -570,7 +896,7 @@ parse_property (ParserData *data,
|
||||
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-flags", &bind_flags_str,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -583,7 +909,7 @@ parse_property (ParserData *data,
|
||||
GTK_BUILDER_ERROR_INVALID_PROPERTY,
|
||||
"Invalid property: %s.%s",
|
||||
g_type_name (object_info->type), name);
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -591,12 +917,12 @@ parse_property (ParserData *data,
|
||||
{
|
||||
if (!_gtk_builder_flags_from_string (G_TYPE_BINDING_FLAGS, NULL, bind_flags_str, &bind_flags, error))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_markup_parse_context_get_position (data->ctx, &line, &col);
|
||||
gtk_buildable_parse_context_get_position (&data->ctx, &line, &col);
|
||||
|
||||
if (bind_source)
|
||||
{
|
||||
@@ -677,7 +1003,7 @@ parse_signal (ParserData *data,
|
||||
G_MARKUP_COLLECT_TRISTATE|G_MARKUP_COLLECT_OPTIONAL, "swapped", &swapped,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -688,7 +1014,7 @@ parse_signal (ParserData *data,
|
||||
GTK_BUILDER_ERROR_INVALID_SIGNAL,
|
||||
"Invalid signal '%s' for type '%s'",
|
||||
name, g_type_name (object_info->type));
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -747,7 +1073,7 @@ parse_interface (ParserData *data,
|
||||
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "domain", &domain,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, data->ctx, error);
|
||||
_gtk_builder_prefix_error (data->builder, &data->ctx, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -769,7 +1095,7 @@ static SubParser *
|
||||
create_subparser (GObject *object,
|
||||
GObject *child,
|
||||
const gchar *element_name,
|
||||
GMarkupParser *parser,
|
||||
GtkBuildableParser *parser,
|
||||
gpointer user_data)
|
||||
{
|
||||
SubParser *subparser;
|
||||
@@ -779,7 +1105,7 @@ create_subparser (GObject *object,
|
||||
subparser->child = child;
|
||||
subparser->tagname = g_strdup (element_name);
|
||||
subparser->start = element_name;
|
||||
subparser->parser = g_memdup (parser, sizeof (GMarkupParser));
|
||||
subparser->parser = g_memdup (parser, sizeof (GtkBuildableParser));
|
||||
subparser->data = user_data;
|
||||
|
||||
return subparser;
|
||||
@@ -793,12 +1119,12 @@ free_subparser (SubParser *subparser)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
subparser_start (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
ParserData *data,
|
||||
GError **error)
|
||||
subparser_start (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
ParserData *data,
|
||||
GError **error)
|
||||
{
|
||||
SubParser *subparser = data->subparser;
|
||||
|
||||
@@ -818,10 +1144,10 @@ subparser_start (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
static void
|
||||
subparser_end (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
ParserData *data,
|
||||
GError **error)
|
||||
subparser_end (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
ParserData *data,
|
||||
GError **error)
|
||||
{
|
||||
if (data->subparser->parser->end_element)
|
||||
data->subparser->parser->end_element (context, element_name,
|
||||
@@ -853,15 +1179,15 @@ subparser_end (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_custom (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
ParserData *data,
|
||||
GError **error)
|
||||
parse_custom (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
ParserData *data,
|
||||
GError **error)
|
||||
{
|
||||
CommonInfo* parent_info;
|
||||
GMarkupParser parser;
|
||||
GtkBuildableParser parser;
|
||||
gpointer subparser_data;
|
||||
GObject *object;
|
||||
GObject *child;
|
||||
@@ -918,12 +1244,12 @@ parse_custom (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
static void
|
||||
start_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
start_element (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
const gchar **names,
|
||||
const gchar **values,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ParserData *data = (ParserData*)user_data;
|
||||
|
||||
@@ -1004,10 +1330,10 @@ _gtk_builder_parser_translate (const gchar *domain,
|
||||
}
|
||||
|
||||
static void
|
||||
end_element (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
end_element (GtkBuildableParseContext *context,
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ParserData *data = (ParserData*)user_data;
|
||||
|
||||
@@ -1158,11 +1484,11 @@ end_element (GMarkupParseContext *context,
|
||||
/* Called for character data */
|
||||
/* text is not nul-terminated */
|
||||
static void
|
||||
text (GMarkupParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
text (GtkBuildableParseContext *context,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ParserData *data = (ParserData*)user_data;
|
||||
CommonInfo *info;
|
||||
@@ -1185,7 +1511,7 @@ text (GMarkupParseContext *context,
|
||||
info = state_peek_info (data, CommonInfo);
|
||||
g_assert (info != NULL);
|
||||
|
||||
if (strcmp (g_markup_parse_context_get_element (context), "property") == 0)
|
||||
if (strcmp (gtk_buildable_parse_context_get_element (context), "property") == 0)
|
||||
{
|
||||
PropertyInfo *prop_info = (PropertyInfo*)info;
|
||||
|
||||
@@ -1219,7 +1545,7 @@ free_info (CommonInfo *info)
|
||||
}
|
||||
}
|
||||
|
||||
static const GMarkupParser parser = {
|
||||
static const GtkBuildableParser parser = {
|
||||
start_element,
|
||||
end_element,
|
||||
text,
|
||||
@@ -1263,11 +1589,9 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
data.inside_requested_object = TRUE;
|
||||
}
|
||||
|
||||
data.ctx = g_markup_parse_context_new (&parser,
|
||||
G_MARKUP_TREAT_CDATA_AS_TEXT,
|
||||
&data, NULL);
|
||||
gtk_buildable_parse_context_init (&data.ctx, &parser, &data);
|
||||
|
||||
if (!g_markup_parse_context_parse (data.ctx, buffer, length, error))
|
||||
if (!gtk_buildable_parse_context_parse (&data.ctx, buffer, length, error))
|
||||
goto out;
|
||||
|
||||
_gtk_builder_finish (builder);
|
||||
@@ -1307,7 +1631,7 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
g_slist_free (data.finalizers);
|
||||
g_free (data.domain);
|
||||
g_hash_table_destroy (data.object_ids);
|
||||
g_markup_parse_context_free (data.ctx);
|
||||
gtk_buildable_parse_context_free (&data.ctx);
|
||||
|
||||
/* restore the original domain */
|
||||
gtk_builder_set_translation_domain (builder, domain);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user