Compare commits
231 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d14a5acd4e | |||
| 4de67b2fe5 | |||
| 6d878bd21c | |||
| 965fd476a5 | |||
| 3bce60c433 | |||
| 8083456599 | |||
| 2a1b8c4fcc | |||
| ed9e759917 | |||
| f69d7f804a | |||
| 4368583cbe | |||
| c44efc31ba | |||
| 3c6cc6c362 | |||
| eff0d5b37b | |||
| 579878a855 | |||
| b43294c1c3 | |||
| 5d8e801d80 | |||
| 4c7631a645 | |||
| 9fe78d9f75 | |||
| 9a7d84b441 | |||
| 1fe9918f3c | |||
| cd04aa1cd4 | |||
| ac1c0d37c6 | |||
| ea6bcdbd3d | |||
| fe83b06eaf | |||
| be5fd3d89f | |||
| bef38bd9c4 | |||
| 06f08ea804 | |||
| 79bb805a02 | |||
| d70c005021 | |||
| 9fc7d8e947 | |||
| b06ac9826c | |||
| 94cacd79f9 | |||
| 17d3631605 | |||
| 3b027cf466 | |||
| 5d4f2822d0 | |||
| 5a11ee7b9c | |||
| 874410129e | |||
| 2cf1651235 | |||
| ad2221ce29 | |||
| 6dd0be2f06 | |||
| 2103ab99a5 | |||
| d7ab7e9628 | |||
| 3d7ac47e5e | |||
| c373e2c76b | |||
| ec3b27bb68 | |||
| 5b87dba1a3 | |||
| 12dcaf1e7a | |||
| 5031f30f28 | |||
| ad465e81aa | |||
| 39374c7209 | |||
| 170a1cd941 | |||
| 6074a18e3e | |||
| 5d5b612630 | |||
| 5942252175 | |||
| 9a3898fe89 | |||
| c6a3efaf70 | |||
| 9870234294 | |||
| 64ecb972cf | |||
| ded6d400d7 | |||
| 979a37d3f7 | |||
| 270e6165f4 | |||
| df51d474fc | |||
| 1e0ab6f249 | |||
| deb4de6332 | |||
| b4c7dd770c | |||
| 7488644176 | |||
| 9ed7cecd42 | |||
| df36ab3f93 | |||
| 7e4fdea71b | |||
| ea8062e86a | |||
| c4efe7709b | |||
| fdea496883 | |||
| 60878e4186 | |||
| 02297138f3 | |||
| 6603e02beb | |||
| bfb7573810 | |||
| 6847c3469d | |||
| 7a1e5b4418 | |||
| 76980e10a0 | |||
| 34f4a06691 | |||
| 2dea5ae958 | |||
| 5856716188 | |||
| 1c4a0dae62 | |||
| b7fba6298f | |||
| 5ce196fe9f | |||
| c31c89c794 | |||
| 1eb8c3ea34 | |||
| b2414b1ecd | |||
| fd3dfaf2c3 | |||
| 43a6c8c5f5 | |||
| 3789191853 | |||
| eb4fb2af0e | |||
| fd02afa2e4 | |||
| 55bb77cffc | |||
| 119ba5844f | |||
| 9b2b5ebb65 | |||
| 1624455a32 | |||
| d483883f38 | |||
| 0dc0bea1d5 | |||
| 55e31b972c | |||
| 1013874de8 | |||
| c397460c11 | |||
| ff0045b8c9 | |||
| d0b409d349 | |||
| c0cb10262d | |||
| 279a5f7825 | |||
| 6fa87d4f37 | |||
| fe35daaf34 | |||
| c3b836951a | |||
| ec10f1fe16 | |||
| ae741a06c0 | |||
| 754c9cb323 | |||
| a3683a080b | |||
| 0673d74986 | |||
| 8c46df425e | |||
| ff78e1888b | |||
| f2f219f304 | |||
| bb46edcc21 | |||
| 24173e3f93 | |||
| ec73bcb05b | |||
| 6c74c9c970 | |||
| c9c35ae41d | |||
| 95cea06462 | |||
| d01ca53bde | |||
| 3d3cafefc8 | |||
| 86cdb0ceb2 | |||
| 0c97c86573 | |||
| 10fa570195 | |||
| e18c553457 | |||
| 187763d286 | |||
| e6ae136de0 | |||
| 81efb63073 | |||
| cbadb1ed8e | |||
| 103e98f570 | |||
| 3768c751c5 | |||
| e42014573a | |||
| a9f1ff471b | |||
| e26a1bbda9 | |||
| b2ae7a2448 | |||
| cb682c759d | |||
| b154c9caf4 | |||
| 523fca21e9 | |||
| 73ddde6eda | |||
| 403da9a2d5 | |||
| fb6f211869 | |||
| c358606a46 | |||
| b7e5a79468 | |||
| 06bcb0ee47 | |||
| 58ce0a39dc | |||
| 6d3c333208 | |||
| 62c3923e5a | |||
| 3be8b1d927 | |||
| 27a61e221f | |||
| 52df3481d6 | |||
| ccb993d87b | |||
| 5fdaa4a232 | |||
| 8b166dff74 | |||
| f6b3f321a4 | |||
| a314143a83 | |||
| 6c7abf425a | |||
| b11e45762b | |||
| d041a681a5 | |||
| d22d2f77a6 | |||
| 7458461d06 | |||
| 283615936b | |||
| 2274bca95b | |||
| f8b4deeac0 | |||
| afa503c2e0 | |||
| 105f5f1137 | |||
| b83ad60a1f | |||
| 58b44ebc1c | |||
| b598f21506 | |||
| d3c166d511 | |||
| 76e93206f3 | |||
| ecfe47af73 | |||
| f20ca9067e | |||
| 8f3cd4733c | |||
| 402ee9b39c | |||
| becbf4e1f9 | |||
| 67407d5dcf | |||
| fcc0f243cf | |||
| 282dcfa9ac | |||
| 8c04801f6a | |||
| abe2d1cb16 | |||
| e407d22b1e | |||
| 37cefde5b0 | |||
| 310a4a3bf6 | |||
| e6896aa8dc | |||
| 36ce68a3ca | |||
| 797343da59 | |||
| bd3223d452 | |||
| 87a1a17868 | |||
| 70f386bd68 | |||
| 0af89088ba | |||
| 7342317c31 | |||
| 8d8bd4efba | |||
| 0ae3c8968e | |||
| 5e3f13acd1 | |||
| 32cdf35583 | |||
| 2f670bdc59 | |||
| 8d5660b4ab | |||
| 2a39f427e1 | |||
| ca86294325 | |||
| 820ba1ef13 | |||
| 9507130dbc | |||
| d2dede635b | |||
| 5a7fc4054b | |||
| 7fe22845e3 | |||
| 6c9a7cc708 | |||
| feeca98270 | |||
| 7c27241479 | |||
| fb73040d70 | |||
| bbe74abf51 | |||
| 34bd3fc854 | |||
| 940b5af2a8 | |||
| 0929d77f7f | |||
| 617297ddd7 | |||
| 67cec180ca | |||
| bab8f2f976 | |||
| 4801c3275e | |||
| 39354b3b99 | |||
| 661e953558 | |||
| 039b97ef9e | |||
| 97e0f872a2 | |||
| de74fa0836 | |||
| 42d26720d6 | |||
| c7dfb8cb55 | |||
| 236b6d1cd6 | |||
| 6e714722c4 | |||
| 2e2dab9c3d | |||
| a6eea6ba3c |
@@ -68,7 +68,6 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gl.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gles2.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
|
||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||
paths:
|
||||
@@ -136,8 +135,6 @@ release-build:
|
||||
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
|
||||
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
||||
- .gitlab-ci/run-tests.sh _build wayland gtk
|
||||
# only repeat test runs that are likely affected by test setups
|
||||
- .gitlab-ci/run-tests.sh _build wayland_gles2 gtk:gdk,gtk:gsk-gl
|
||||
|
||||
fedora-clang:
|
||||
extends: .build-fedora-default
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
<!--
|
||||
- Which version of GTK you are using
|
||||
- What operating system and version
|
||||
- For Linux, which distribution
|
||||
- What windowing system (X11 or Wayland)
|
||||
- What graphics driver / mesa version
|
||||
- For Linux, which distribution
|
||||
- If you built GTK yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
|
||||
@@ -1,65 +1,8 @@
|
||||
Overview of Changes in 4.16.4, 01-11-2024
|
||||
Overview of Changes in 4.17.0, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
* GtkTextView:
|
||||
- Fix some missing CSS invalidation
|
||||
- Handle charsets in clipboard datatypes
|
||||
|
||||
* GtkApplication:
|
||||
- Respect GDK_DEBUG=no-portals
|
||||
|
||||
* Printing:
|
||||
- Avoid warnings for avahi errors
|
||||
- Fix a segfault in the print dialog setup code
|
||||
|
||||
* Accessibility:
|
||||
- Handle NULL values in more places
|
||||
|
||||
* Gdk:
|
||||
- vulkan: Fix validation errors
|
||||
- Fix 32bit build for the jpeg loader
|
||||
|
||||
* Wayland:
|
||||
- Fix a possible deadlock with high-priority sources
|
||||
triggering Wayland roundtrips
|
||||
|
||||
* Translation updates
|
||||
Belarusian
|
||||
British English
|
||||
Latvian
|
||||
Romanian
|
||||
|
||||
|
||||
Overview of Changes in 4.16.3, 04-10-2024
|
||||
=========================================
|
||||
|
||||
* GtkScrolledWindow
|
||||
- Fix criticals in size allocation code
|
||||
|
||||
* GtkFileChooser
|
||||
- Fix a crash in the portal code
|
||||
|
||||
* GtkPicture
|
||||
- Avoid unnecessary resizes
|
||||
|
||||
* GtkVideo
|
||||
- Make dmabufs work without GL
|
||||
|
||||
* Accessibility:
|
||||
- Always realized non-widget accessibles
|
||||
|
||||
* Wayland:
|
||||
- Improve settings portal handling
|
||||
- Improve fallback for cursor themes
|
||||
- Sync default values for settings with schema defaults
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
Galician
|
||||
Swedish
|
||||
|
||||
|
||||
Overview of Changes in 4.16.2, 25-09-2024
|
||||
Overview of Changes in 4.16.2, 09-25-2024
|
||||
=========================================
|
||||
|
||||
* GtkLabel:
|
||||
@@ -100,7 +43,7 @@ Overview of Changes in 4.16.2, 25-09-2024
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.16.1, 16-09-2024
|
||||
Overview of Changes in 4.16.1, 09-16-2024
|
||||
=========================================
|
||||
|
||||
* GtkFileChooser:
|
||||
@@ -141,7 +84,7 @@ Overview of Changes in 4.16.1, 16-09-2024
|
||||
Swedish
|
||||
|
||||
|
||||
Overview of Changes in 4.16.0, 06-09-2024
|
||||
Overview of Changes in 4.16.0, 09-06-2024
|
||||
=========================================
|
||||
|
||||
Note: This release changes the default GSK renderer to be Vulkan,
|
||||
@@ -239,7 +182,7 @@ with the new renderers.
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.15.6, 26-08-2024
|
||||
Overview of Changes in 4.15.6, 08-26-2024
|
||||
=========================================
|
||||
|
||||
* GtkCheckButton:
|
||||
|
||||
@@ -136,9 +136,13 @@ In the bug report please include:
|
||||
|
||||
- which version of GTK you are using
|
||||
- what operating system and version
|
||||
- what windowing system (X11 or Wayland)
|
||||
- what graphics driver / mesa version
|
||||
- for Linux, which distribution
|
||||
- if you built GTK, the list of options used to configure the build
|
||||
|
||||
Most of this information can be found in the GTK inspector.
|
||||
|
||||
And anything else you think is relevant.
|
||||
|
||||
* How to reproduce the bug.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
uniform float u_time;
|
||||
|
||||
void
|
||||
mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||
{
|
||||
vec2 pos = (fragCoord.xy * 2.0 - resolution.xy)/ min (resolution.x, resolution.y) ;
|
||||
|
||||
float t0 = sin ((u_time + 0.00)*1.0);
|
||||
float t1 = sin ((u_time + 0.30)*0.4);
|
||||
float t2 = cos ((u_time + 0.23)*0.9);
|
||||
float t3 = cos ((u_time + 0.41)*0.6);
|
||||
float t4 = cos ((u_time + 0.11)*0.3);
|
||||
|
||||
vec2 p0 = vec2 (t1, t0) ;
|
||||
vec2 p1 = vec2 (t2, t3) ;
|
||||
vec2 p2 = vec2 (t4, t3) ;
|
||||
|
||||
float r = 1.0/distance (pos, p0);
|
||||
float g = 1.0/distance (pos, p1);
|
||||
float b = 1.0/distance (pos, p2);
|
||||
float sum = r + g + b;
|
||||
|
||||
float alpha = 1.0 - pow (1.0/(sum), 40.0)*pow (10.0, 40.0*0.7);
|
||||
|
||||
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
|
||||
}
|
||||
@@ -1,226 +0,0 @@
|
||||
uniform float iTime;
|
||||
|
||||
// Originally from: https://www.shadertoy.com/view/3ljyDD
|
||||
// License CC0: Hexagonal tiling + cog wheels
|
||||
// Nothing fancy, just hexagonal tiling + cog wheels
|
||||
|
||||
#define PI 3.141592654
|
||||
#define TAU (2.0*PI)
|
||||
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
|
||||
|
||||
float hash(in vec2 co) {
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
|
||||
}
|
||||
|
||||
float pcos(float a) {
|
||||
return 0.5 + 0.5*cos(a);
|
||||
}
|
||||
|
||||
void rot(inout vec2 p, float a) {
|
||||
float c = cos(a);
|
||||
float s = sin(a);
|
||||
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
|
||||
}
|
||||
|
||||
float modPolar(inout vec2 p, float repetitions) {
|
||||
float angle = 2.0*PI/repetitions;
|
||||
float a = atan(p.y, p.x) + angle/2.;
|
||||
float r = length(p);
|
||||
float c = floor(a/angle);
|
||||
a = mod(a,angle) - angle/2.;
|
||||
p = vec2(cos(a), sin(a))*r;
|
||||
// For an odd number of repetitions, fix cell index of the cell in -x direction
|
||||
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
|
||||
if (abs(c) >= (repetitions/2.0)) c = abs(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
float pmin(float a, float b, float k) {
|
||||
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
|
||||
return mix( b, a, h ) - k*h*(1.0-h);
|
||||
}
|
||||
|
||||
const vec2 sz = vec2(1.0, sqrt(3.0));
|
||||
const vec2 hsz = 0.5*sz;
|
||||
const float smallCount = 16.0;
|
||||
|
||||
vec2 hextile(inout vec2 p) {
|
||||
// See Art of Code: Hexagonal Tiling Explained!
|
||||
// https://www.youtube.com/watch?v=VmrIDyYiJBA
|
||||
|
||||
vec2 p1 = mod(p, sz)-hsz;
|
||||
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
|
||||
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
|
||||
vec2 n = p3 - p;
|
||||
p = p3;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
float circle(vec2 p, float r) {
|
||||
return length(p) - r;
|
||||
}
|
||||
|
||||
float box(vec2 p, vec2 b) {
|
||||
vec2 d = abs(p)-b;
|
||||
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
|
||||
}
|
||||
|
||||
float unevenCapsule(vec2 p, float r1, float r2, float h) {
|
||||
p.x = abs(p.x);
|
||||
float b = (r1-r2)/h;
|
||||
float a = sqrt(1.0-b*b);
|
||||
float k = dot(p,vec2(-b,a));
|
||||
if( k < 0.0 ) return length(p) - r1;
|
||||
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
|
||||
return dot(p, vec2(a,b) ) - r1;
|
||||
}
|
||||
|
||||
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
|
||||
float cogWidth = 0.25*innerRadius*TAU/cogs;
|
||||
|
||||
float d0 = circle(p, innerRadius);
|
||||
|
||||
vec2 icp = p;
|
||||
modPolar(icp, holes);
|
||||
icp -= vec2(innerRadius*0.55, 0.0);
|
||||
float d1 = circle(icp, innerRadius*0.25);
|
||||
|
||||
vec2 cp = p;
|
||||
modPolar(cp, cogs);
|
||||
cp -= vec2(innerRadius, 0.0);
|
||||
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
|
||||
|
||||
float d3 = circle(p, innerRadius*0.20);
|
||||
|
||||
float d = 1E6;
|
||||
d = min(d, d0);
|
||||
d = pmin(d, d2, 0.5*cogWidth);
|
||||
d = min(d, d2);
|
||||
d = max(d, -d1);
|
||||
d = max(d, -d3);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
float ccell1(vec2 p, float r) {
|
||||
float d = 1E6;
|
||||
const float bigCount = 60.0;
|
||||
|
||||
vec2 cp0 = p;
|
||||
rot(cp0, -iTime*TAU/bigCount);
|
||||
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
|
||||
|
||||
vec2 cp1 = p;
|
||||
float nm = modPolar(cp1, 6.0);
|
||||
|
||||
cp1 -= vec2(0.5, 0.0);
|
||||
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
|
||||
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
|
||||
|
||||
d = min(d, d0);
|
||||
d = min(d, d1);
|
||||
return d;
|
||||
}
|
||||
|
||||
float ccell2(vec2 p, float r) {
|
||||
float d = 1E6;
|
||||
vec2 cp0 = p;
|
||||
float nm = modPolar(cp0, 6.0);
|
||||
vec2 cp1 = cp0;
|
||||
const float off = 0.275;
|
||||
const float count = smallCount + 2.0;
|
||||
cp0 -= vec2(off, 0.0);
|
||||
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
|
||||
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
|
||||
|
||||
|
||||
cp1 -= vec2(0.5, 0.0);
|
||||
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
|
||||
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
|
||||
|
||||
float l = length(p);
|
||||
float d2 = l - (off+0.055);
|
||||
float d3 = d2 + 0.020;;
|
||||
|
||||
vec2 tp0 = p;
|
||||
modPolar(tp0, 60.0);
|
||||
tp0.x -= off;
|
||||
float d4 = box(tp0, vec2(0.0125, 0.005));
|
||||
|
||||
float ctime = -(iTime*0.05 + r)*TAU;
|
||||
|
||||
vec2 tp1 = p;
|
||||
rot(tp1, ctime*12.0);
|
||||
tp1.x -= 0.13;
|
||||
float d5 = box(tp1, vec2(0.125, 0.005));
|
||||
|
||||
vec2 tp2 = p;
|
||||
rot(tp2, ctime);
|
||||
tp2.x -= 0.13*0.5;
|
||||
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
|
||||
|
||||
float d7 = l - 0.025;
|
||||
float d8 = l - 0.0125;
|
||||
|
||||
d = min(d, d0);
|
||||
d = min(d, d1);
|
||||
d = min(d, d2);
|
||||
d = max(d, -d3);
|
||||
d = min(d, d4);
|
||||
d = min(d, d5);
|
||||
d = min(d, d6);
|
||||
d = min(d, d7);
|
||||
d = max(d, -d8);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
float df(vec2 p, float scale, inout vec2 nn) {
|
||||
p /= scale;
|
||||
nn = hextile(p);
|
||||
nn = floor(nn + 0.5);
|
||||
float r = hash(nn);
|
||||
|
||||
float d;;
|
||||
|
||||
if (r < 0.5) {
|
||||
d = ccell1(p, r);
|
||||
} else {
|
||||
d = ccell2(p, r);
|
||||
}
|
||||
|
||||
return d*scale;
|
||||
}
|
||||
|
||||
vec3 postProcess(vec3 col, vec2 q) {
|
||||
//col = saturate(col);
|
||||
col=pow(clamp(col,0.0,1.0),vec3(0.75));
|
||||
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
|
||||
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
|
||||
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
|
||||
return col;
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv) {
|
||||
vec2 q = fragCoord/resolution.xy;
|
||||
vec2 p = -1.0 + 2.0*q;
|
||||
p.x *= resolution.x/resolution.y;
|
||||
float tm = iTime*0.1;
|
||||
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
|
||||
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
|
||||
float aa = 4.0 / resolution.y;
|
||||
|
||||
vec2 nn = vec2(0.0);
|
||||
float d = df(p, z, nn);
|
||||
|
||||
vec3 col = vec3(160.0)/vec3(255.0);
|
||||
vec3 baseCol = vec3(0.3);
|
||||
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
|
||||
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
|
||||
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
|
||||
|
||||
col = postProcess(col, q);
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
uniform float progress;
|
||||
uniform sampler2D u_texture1;
|
||||
uniform sampler2D u_texture2;
|
||||
|
||||
vec4 getFromColor (vec2 uv) {
|
||||
return GskTexture(u_texture1, uv);
|
||||
}
|
||||
|
||||
vec4 getToColor (vec2 uv) {
|
||||
return GskTexture(u_texture2, uv);
|
||||
}
|
||||
|
||||
// Source: https://gl-transitions.com/editor/crosswarp
|
||||
// Author: Eke Péter <peterekepeter@gmail.com>
|
||||
// License: MIT
|
||||
|
||||
vec4 transition(vec2 p) {
|
||||
float x = progress;
|
||||
x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
|
||||
return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
|
||||
}
|
||||
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||
{
|
||||
fragColor = transition(uv);
|
||||
}
|
||||
@@ -146,21 +146,6 @@
|
||||
<file>cogs.glsl</file>
|
||||
<file>glowingstars.glsl</file>
|
||||
</gresource>
|
||||
<gresource prefix="/gltransition">
|
||||
<file>gtkshaderstack.c</file>
|
||||
<file>gtkshaderstack.h</file>
|
||||
<file>gtkshaderbin.h</file>
|
||||
<file>gtkshaderbin.c</file>
|
||||
<file>gskshaderpaintable.h</file>
|
||||
<file>gskshaderpaintable.c</file>
|
||||
<file>wind.glsl</file>
|
||||
<file>radial.glsl</file>
|
||||
<file>crosswarp.glsl</file>
|
||||
<file>kaleidoscope.glsl</file>
|
||||
<file>cogs2.glsl</file>
|
||||
<file>ripple.glsl</file>
|
||||
<file>background.glsl</file>
|
||||
</gresource>
|
||||
<gresource prefix="/iconscroll">
|
||||
<file>iconscroll.ui</file>
|
||||
</gresource>
|
||||
@@ -296,7 +281,6 @@
|
||||
<file>gears.c</file>
|
||||
<file>gestures.c</file>
|
||||
<file>glarea.c</file>
|
||||
<file>gltransition.c</file>
|
||||
<file>headerbar.c</file>
|
||||
<file>hypertext.c</file>
|
||||
<file>iconscroll.c</file>
|
||||
@@ -457,6 +441,7 @@
|
||||
<file>portland-rose-thumbnail.png</file>
|
||||
<file>large-image-thumbnail.png</file>
|
||||
<file compressed="true">large-image.png</file>
|
||||
<file compressed="true">Moby-Dick.txt</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4/gtk">
|
||||
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "gtkfishbowl.h"
|
||||
#include "gtkgears.h"
|
||||
#include "gskshaderpaintable.h"
|
||||
|
||||
#include "nodewidget.h"
|
||||
#include "graphwidget.h"
|
||||
@@ -152,46 +151,6 @@ create_switch (void)
|
||||
return w;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_paintable (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
GskShaderPaintable *paintable;
|
||||
gint64 frame_time;
|
||||
|
||||
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
|
||||
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
gsk_shader_paintable_update_time (paintable, 0, frame_time);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_cogs (void)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
GtkWidget *picture;
|
||||
static GskGLShader *cog_shader = NULL;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
if (cog_shader == NULL)
|
||||
cog_shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
|
||||
paintable = gsk_shader_paintable_new (g_object_ref (cog_shader), NULL);
|
||||
picture = gtk_picture_new_for_paintable (paintable);
|
||||
gtk_widget_set_size_request (picture, 150, 75);
|
||||
gtk_widget_add_tick_callback (picture, update_paintable, NULL, NULL);
|
||||
|
||||
return picture;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_cogs (GtkFishbowl *fb)
|
||||
{
|
||||
return GSK_IS_GL_RENDERER (gtk_native_get_renderer (gtk_widget_get_native (GTK_WIDGET (fb))));
|
||||
}
|
||||
|
||||
static void
|
||||
mapped (GtkWidget *w)
|
||||
{
|
||||
@@ -241,7 +200,6 @@ static const struct {
|
||||
{ "Gears", create_gears, NULL },
|
||||
{ "Switch", create_switch, NULL },
|
||||
{ "Menubutton", create_menu_button, NULL },
|
||||
{ "Shader", create_cogs, check_cogs },
|
||||
{ "Tiger", create_tiger, NULL },
|
||||
{ "Graph", create_graph, NULL },
|
||||
};
|
||||
|
||||
@@ -276,7 +276,7 @@ gtk_font_plane_class_init (GtkFontPlaneClass *class)
|
||||
|
||||
GtkWidget *
|
||||
gtk_font_plane_new (GtkAdjustment *weight_adj,
|
||||
GtkAdjustment *width_adj)
|
||||
GtkAdjustment *width_adj)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_FONT_PLANE,
|
||||
"weight-adjustment", weight_adj,
|
||||
|
||||
@@ -55,7 +55,7 @@ struct _GtkFontPlaneClass
|
||||
|
||||
|
||||
GType gtk_font_plane_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget * gtk_font_plane_new (GtkAdjustment *width_adj,
|
||||
GtkAdjustment *weight_adj);
|
||||
GtkWidget * gtk_font_plane_new (GtkAdjustment *weight_adj,
|
||||
GtkAdjustment *width_adj);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -1,366 +0,0 @@
|
||||
/* OpenGL/Transitions and Effects
|
||||
* #Keywords: OpenGL, shader, effect
|
||||
*
|
||||
* Create transitions between pages using a custom fragment shader.
|
||||
*
|
||||
* The example transitions here are taken from gl-transitions.com, and you
|
||||
* can edit the shader code itself on the last page of the stack.
|
||||
*
|
||||
* The transitions work with arbitrary content. We use images, shaders
|
||||
* GL areas and plain old widgets to demonstrate this.
|
||||
*
|
||||
* The demo also shows some over-the-top effects like wobbly widgets,
|
||||
* and animated backgrounds.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtkshaderstack.h"
|
||||
#include "gtkshaderbin.h"
|
||||
#include "gtkshadertoy.h"
|
||||
#include "gskshaderpaintable.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *demo_window = NULL;
|
||||
|
||||
static void
|
||||
close_window (GtkWidget *widget)
|
||||
{
|
||||
/* Reset the state */
|
||||
demo_window = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
text_changed (GtkTextBuffer *buffer,
|
||||
GtkWidget *button)
|
||||
{
|
||||
gtk_widget_set_visible (button, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_text (GtkWidget *button,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
GskGLShader *shader;
|
||||
GtkTextIter start, end;
|
||||
char *text;
|
||||
|
||||
stack = g_object_get_data (G_OBJECT (button), "the-stack");
|
||||
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
|
||||
|
||||
GBytes *bytes = g_bytes_new_take (text, strlen (text));
|
||||
shader = gsk_gl_shader_new_from_bytes (bytes);
|
||||
|
||||
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
|
||||
|
||||
g_object_unref (shader);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
gtk_widget_set_visible (button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
go_back (GtkWidget *button,
|
||||
GtkWidget *stack)
|
||||
{
|
||||
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
go_forward (GtkWidget *button,
|
||||
GtkWidget *stack)
|
||||
{
|
||||
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
clicked_cb (GtkGestureClick *gesture,
|
||||
guint n_pressed,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
ripple_bin_new (void)
|
||||
{
|
||||
GtkWidget *bin = gtk_shader_bin_new ();
|
||||
static GskGLShader *shader = NULL;
|
||||
|
||||
if (shader == NULL)
|
||||
shader = gsk_gl_shader_new_from_resource ("/gltransition/ripple.glsl");
|
||||
|
||||
gtk_shader_bin_add_shader (GTK_SHADER_BIN (bin), shader, GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_PRELIGHT, 20);
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
new_shadertoy (const char *path)
|
||||
{
|
||||
GBytes *shader;
|
||||
GtkWidget *toy;
|
||||
|
||||
toy = gtk_shadertoy_new ();
|
||||
shader = g_resources_lookup_data (path, 0, NULL);
|
||||
gtk_shadertoy_set_image_shader (GTK_SHADERTOY (toy),
|
||||
g_bytes_get_data (shader, NULL));
|
||||
g_bytes_unref (shader);
|
||||
|
||||
return toy;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_paintable (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
GskShaderPaintable *paintable;
|
||||
gint64 frame_time;
|
||||
|
||||
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
|
||||
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
gsk_shader_paintable_update_time (paintable, 0, frame_time);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
make_shader_stack (const char *name,
|
||||
const char *resource_path,
|
||||
int active_child,
|
||||
GtkWidget *scale)
|
||||
{
|
||||
GtkWidget *stack, *child, *widget, *vbox, *hbox, *bin;
|
||||
GtkWidget *label, *button, *tv;
|
||||
GskGLShader *shader;
|
||||
GObjectClass *class;
|
||||
GParamSpecFloat *pspec;
|
||||
GtkAdjustment *adjustment;
|
||||
GtkTextBuffer *buffer;
|
||||
GBytes *bytes;
|
||||
GtkEventController *controller;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
stack = gtk_shader_stack_new ();
|
||||
shader = gsk_gl_shader_new_from_resource (resource_path);
|
||||
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
|
||||
g_object_unref (shader);
|
||||
|
||||
child = gtk_picture_new_for_resource ("/css_blendmodes/ducky.png");
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
|
||||
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
|
||||
|
||||
shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
|
||||
paintable = gsk_shader_paintable_new (shader, NULL);
|
||||
|
||||
child = gtk_picture_new_for_paintable (paintable);
|
||||
gtk_widget_add_tick_callback (child, update_paintable, NULL, NULL);
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
|
||||
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
|
||||
|
||||
child = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
|
||||
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
|
||||
|
||||
child = new_shadertoy ("/shadertoy/neon.glsl");
|
||||
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
|
||||
|
||||
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||
|
||||
class = g_type_class_ref (GTK_TYPE_SHADER_STACK);
|
||||
pspec = G_PARAM_SPEC_FLOAT (g_object_class_find_property (class, "duration"));
|
||||
|
||||
adjustment = gtk_range_get_adjustment (GTK_RANGE (scale));
|
||||
if (gtk_adjustment_get_lower (adjustment) == 0.0 &&
|
||||
gtk_adjustment_get_upper (adjustment) == 0.0)
|
||||
{
|
||||
gtk_adjustment_configure (adjustment,
|
||||
pspec->default_value,
|
||||
pspec->minimum,
|
||||
pspec->maximum,
|
||||
0.1, 0.5, 0);
|
||||
}
|
||||
|
||||
g_type_class_unref (class);
|
||||
|
||||
g_object_bind_property (adjustment, "value",
|
||||
stack, "duration",
|
||||
G_BINDING_DEFAULT);
|
||||
|
||||
widget = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (widget), TRUE);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_widget_set_vexpand (widget, TRUE);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0);
|
||||
g_signal_connect (controller, "released", G_CALLBACK (clicked_cb), NULL);
|
||||
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (GTK_WIDGET (widget), controller);
|
||||
|
||||
tv = gtk_text_view_new ();
|
||||
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (tv), 4);
|
||||
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (tv), 4);
|
||||
gtk_text_view_set_top_margin (GTK_TEXT_VIEW (tv), 4);
|
||||
gtk_text_view_set_bottom_margin (GTK_TEXT_VIEW (tv), 4);
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
|
||||
bytes = g_resources_lookup_data (resource_path, 0, NULL);
|
||||
gtk_text_buffer_set_text (buffer,
|
||||
(const char *)g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes));
|
||||
g_bytes_unref (bytes);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (widget), tv);
|
||||
|
||||
gtk_box_append (GTK_BOX (child), widget);
|
||||
|
||||
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
|
||||
|
||||
gtk_shader_stack_set_active (GTK_SHADER_STACK (stack), active_child);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||
|
||||
widget = gtk_center_box_new ();
|
||||
label = gtk_label_new (name);
|
||||
gtk_widget_add_css_class (label, "title-4");
|
||||
gtk_widget_set_size_request (label, -1, 26);
|
||||
gtk_center_box_set_center_widget (GTK_CENTER_BOX (widget), label);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("view-refresh-symbolic");
|
||||
g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), button);
|
||||
g_object_set_data (G_OBJECT (button), "the-stack", stack);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (apply_text), buffer);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_add_css_class (button, "small");
|
||||
gtk_widget_set_visible (button, FALSE);
|
||||
gtk_center_box_set_end_widget (GTK_CENTER_BOX (widget), button);
|
||||
|
||||
gtk_box_append (GTK_BOX (vbox), widget);
|
||||
|
||||
GtkWidget *bin2 = ripple_bin_new ();
|
||||
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin2), stack);
|
||||
|
||||
gtk_box_append (GTK_BOX (vbox), bin2);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
|
||||
|
||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (go_back), stack);
|
||||
bin = ripple_bin_new ();
|
||||
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
|
||||
gtk_box_append (GTK_BOX (hbox), bin);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("go-next-symbolic");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (go_forward), stack);
|
||||
bin = ripple_bin_new ();
|
||||
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
|
||||
gtk_box_append (GTK_BOX (hbox), bin);
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_provider (gpointer data)
|
||||
{
|
||||
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_gltransition_window (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
|
||||
GdkPaintable *paintable;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Transitions and Effects");
|
||||
headerbar = gtk_header_bar_new ();
|
||||
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
|
||||
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
|
||||
gtk_widget_set_size_request (scale, 100, -1);
|
||||
gtk_widget_set_tooltip_text (scale, "Transition duration");
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), scale);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
||||
|
||||
outer_grid = gtk_grid_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), outer_grid);
|
||||
|
||||
paintable = gsk_shader_paintable_new (gsk_gl_shader_new_from_resource ("/gltransition/background.glsl"), NULL);
|
||||
background = gtk_picture_new_for_paintable (paintable);
|
||||
gtk_widget_add_tick_callback (background, update_paintable, NULL, NULL);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (outer_grid),
|
||||
background,
|
||||
0, 0, 1, 1);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_grid_attach (GTK_GRID (outer_grid),
|
||||
grid,
|
||||
0, 0, 1, 1);
|
||||
|
||||
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_margin_start (grid, 12);
|
||||
gtk_widget_set_margin_end (grid, 12);
|
||||
gtk_widget_set_margin_top (grid, 12);
|
||||
gtk_widget_set_margin_bottom (grid, 12);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
|
||||
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
|
||||
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
make_shader_stack ("Wind", "/gltransition/wind.glsl", 0, scale),
|
||||
0, 0, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
make_shader_stack ("Radial", "/gltransition/radial.glsl", 1, scale),
|
||||
1, 0, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
make_shader_stack ("Crosswarp", "/gltransition/crosswarp.glsl", 2, scale),
|
||||
0, 1, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
make_shader_stack ("Kaleidoscope", "/gltransition/kaleidoscope.glsl", 3, scale),
|
||||
1, 1, 1, 1);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_string (provider, "button.small { padding: 0; }");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_gltransition (GtkWidget *do_widget)
|
||||
{
|
||||
if (!demo_window)
|
||||
demo_window = create_gltransition_window (do_widget);
|
||||
|
||||
if (!gtk_widget_get_visible (demo_window))
|
||||
gtk_widget_set_visible (demo_window, TRUE);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (demo_window));
|
||||
|
||||
return demo_window;
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
@@ -1,338 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gskshaderpaintable.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
/**
|
||||
* GskShaderPaintable:
|
||||
*
|
||||
* `GskShaderPaintable` is an implementation of the `GdkPaintable` interface
|
||||
* that uses a `GskGLShader` to create pixels.
|
||||
*
|
||||
* You can set the uniform data that the shader needs for rendering
|
||||
* using gsk_shader_paintable_set_args(). This function can
|
||||
* be called repeatedly to change the uniform data for the next
|
||||
* snapshot.
|
||||
*
|
||||
* Commonly, time is passed to shaders as a float uniform containing
|
||||
* the elapsed time in seconds. The convenience API
|
||||
* gsk_shader_paintable_update_time() can be called from a `GtkTickCallback`
|
||||
* to update the time based on the frame time of the frame clock.
|
||||
*/
|
||||
|
||||
|
||||
struct _GskShaderPaintable
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GskGLShader *shader;
|
||||
GBytes *args;
|
||||
|
||||
gint64 start_time;
|
||||
};
|
||||
|
||||
struct _GskShaderPaintableClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_SHADER,
|
||||
PROP_ARGS,
|
||||
|
||||
N_PROPS,
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
static void
|
||||
gsk_shader_paintable_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (paintable);
|
||||
|
||||
gtk_snapshot_push_gl_shader (snapshot, self->shader, &GRAPHENE_RECT_INIT(0, 0, width, height), g_bytes_ref (self->args));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_paintable_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = gsk_shader_paintable_paintable_snapshot;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (GskShaderPaintable, gsk_shader_paintable, G_TYPE_OBJECT, 0,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gsk_shader_paintable_paintable_init))
|
||||
|
||||
static void
|
||||
gsk_shader_paintable_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
|
||||
{
|
||||
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SHADER:
|
||||
gsk_shader_paintable_set_shader (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_ARGS:
|
||||
gsk_shader_paintable_set_args (self, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_paintable_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SHADER:
|
||||
g_value_set_object (value, self->shader);
|
||||
break;
|
||||
|
||||
case PROP_ARGS:
|
||||
g_value_set_boxed (value, self->args);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_paintable_finalize (GObject *object)
|
||||
{
|
||||
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
|
||||
|
||||
g_clear_pointer (&self->args, g_bytes_unref);
|
||||
g_clear_object (&self->shader);
|
||||
|
||||
G_OBJECT_CLASS (gsk_shader_paintable_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_paintable_class_init (GskShaderPaintableClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gsk_shader_paintable_get_property;
|
||||
gobject_class->set_property = gsk_shader_paintable_set_property;
|
||||
gobject_class->finalize = gsk_shader_paintable_finalize;
|
||||
|
||||
properties[PROP_SHADER] =
|
||||
g_param_spec_object ("shader", "Shader", "The shader",
|
||||
GSK_TYPE_GL_SHADER,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_ARGS] =
|
||||
g_param_spec_boxed ("args", "Arguments", "The uniform arguments",
|
||||
G_TYPE_BYTES,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_shader_paintable_init (GskShaderPaintable *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_shader_paintable_new:
|
||||
* @shader: (transfer full) (nullable): the shader to use
|
||||
* @data: (transfer full) (nullable): uniform data
|
||||
*
|
||||
* Creates a paintable that uses the @shader to create
|
||||
* pixels. The shader must not require input textures.
|
||||
* If @data is %NULL, all uniform values are set to zero.
|
||||
*
|
||||
* Returns: (transfer full): a new `GskShaderPaintable`
|
||||
*/
|
||||
GdkPaintable *
|
||||
gsk_shader_paintable_new (GskGLShader *shader,
|
||||
GBytes *data)
|
||||
{
|
||||
GdkPaintable *ret;
|
||||
|
||||
g_return_val_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader), NULL);
|
||||
|
||||
if (shader && !data)
|
||||
{
|
||||
int size = gsk_gl_shader_get_args_size (shader);
|
||||
data = g_bytes_new_take (g_new0 (guchar, size), size);
|
||||
}
|
||||
|
||||
ret = g_object_new (GSK_TYPE_SHADER_PAINTABLE,
|
||||
"shader", shader,
|
||||
"args", data,
|
||||
NULL);
|
||||
|
||||
g_clear_object (&shader);
|
||||
g_clear_pointer (&data, g_bytes_unref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_shader_paintable_set_shader:
|
||||
* @self: a `GskShaderPaintable`
|
||||
* @shader: the `GskGLShader` to use
|
||||
*
|
||||
* Sets the shader that the paintable will use
|
||||
* to create pixels. The shader must not require
|
||||
* input textures.
|
||||
*/
|
||||
void
|
||||
gsk_shader_paintable_set_shader (GskShaderPaintable *self,
|
||||
GskGLShader *shader)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
|
||||
g_return_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader));
|
||||
g_return_if_fail (shader == NULL || gsk_gl_shader_get_n_textures (shader) == 0);
|
||||
|
||||
if (!g_set_object (&self->shader, shader))
|
||||
return;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHADER]);
|
||||
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
|
||||
|
||||
g_clear_pointer (&self->args, g_bytes_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_shader_paintable_get_shader:
|
||||
* @self: a `GskShaderPaintable`
|
||||
*
|
||||
* Returns the shader that the paintable is using.
|
||||
*
|
||||
* Returns: (transfer none): the `GskGLShader` that is used
|
||||
*/
|
||||
GskGLShader *
|
||||
gsk_shader_paintable_get_shader (GskShaderPaintable *self)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
|
||||
|
||||
return self->shader;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_shader_paintable_set_args:
|
||||
* @self: a `GskShaderPaintable`
|
||||
* @data: Data block with uniform data for the shader
|
||||
*
|
||||
* Sets the uniform data that will be passed to the
|
||||
* shader when rendering. The @data will typically
|
||||
* be produced by a `GskUniformDataBuilder`.
|
||||
*
|
||||
* Note that the @data should be considered immutable
|
||||
* after it has been passed to this function.
|
||||
*/
|
||||
void
|
||||
gsk_shader_paintable_set_args (GskShaderPaintable *self,
|
||||
GBytes *data)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
|
||||
g_return_if_fail (data == NULL || g_bytes_get_size (data) == gsk_gl_shader_get_args_size (self->shader));
|
||||
|
||||
g_clear_pointer (&self->args, g_bytes_unref);
|
||||
if (data)
|
||||
self->args = g_bytes_ref (data);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ARGS]);
|
||||
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_shader_paintable_get_args:
|
||||
* @self: a `GskShaderPaintable`
|
||||
*
|
||||
* Returns the uniform data set with
|
||||
* gsk_shader_paintable_get_args().
|
||||
*
|
||||
* Returns: (transfer none): the uniform data
|
||||
*/
|
||||
GBytes *
|
||||
gsk_shader_paintable_get_args (GskShaderPaintable *self)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
|
||||
|
||||
return self->args;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_shader_paintable_update_time:
|
||||
* @self: a `GskShaderPaintable`
|
||||
* @time_idx: the index of the uniform for time in seconds as float
|
||||
* @frame_time: the current frame time, as returned by `GdkFrameClock`
|
||||
*
|
||||
* This function is a convenience wrapper for
|
||||
* gsk_shader_paintable_set_args() that leaves all
|
||||
* uniform values unchanged, except for the uniform with
|
||||
* index @time_idx, which will be set to the elapsed time
|
||||
* in seconds, since the first call to this function.
|
||||
*
|
||||
* This function is usually called from a `GtkTickCallback`.
|
||||
*/
|
||||
void
|
||||
gsk_shader_paintable_update_time (GskShaderPaintable *self,
|
||||
int time_idx,
|
||||
gint64 frame_time)
|
||||
{
|
||||
GskShaderArgsBuilder *builder;
|
||||
GBytes *args;
|
||||
float time;
|
||||
|
||||
if (self->start_time == 0)
|
||||
self->start_time = frame_time;
|
||||
|
||||
time = (frame_time - self->start_time) / (float)G_TIME_SPAN_SECOND;
|
||||
|
||||
builder = gsk_shader_args_builder_new (self->shader, self->args);
|
||||
gsk_shader_args_builder_set_float (builder, time_idx, time);
|
||||
args = gsk_shader_args_builder_free_to_args (builder);
|
||||
|
||||
gsk_shader_paintable_set_args (self, args);
|
||||
|
||||
g_bytes_unref (args);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gsk/gsk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_TYPE_SHADER_PAINTABLE (gsk_shader_paintable_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GskShaderPaintable, gsk_shader_paintable, GSK, SHADER_PAINTABLE, GObject)
|
||||
|
||||
GdkPaintable * gsk_shader_paintable_new (GskGLShader *shader,
|
||||
GBytes *data);
|
||||
|
||||
GskGLShader * gsk_shader_paintable_get_shader (GskShaderPaintable *self);
|
||||
void gsk_shader_paintable_set_shader (GskShaderPaintable *self,
|
||||
GskGLShader *shader);
|
||||
GBytes * gsk_shader_paintable_get_args (GskShaderPaintable *self);
|
||||
void gsk_shader_paintable_set_args (GskShaderPaintable *self,
|
||||
GBytes *data);
|
||||
void gsk_shader_paintable_update_time (GskShaderPaintable *self,
|
||||
int time_idx,
|
||||
gint64 frame_time);
|
||||
G_END_DECLS
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
@@ -55,7 +55,7 @@ void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
||||
gboolean animating);
|
||||
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
|
||||
gboolean animating);
|
||||
gboolean benchmark);
|
||||
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
|
||||
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
#include "gtkshaderbin.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef struct {
|
||||
GskGLShader *shader;
|
||||
GtkStateFlags state;
|
||||
GtkStateFlags state_mask;
|
||||
float extra_border;
|
||||
gboolean compiled;
|
||||
gboolean compiled_ok;
|
||||
} ShaderInfo;
|
||||
|
||||
struct _GtkShaderBin
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
GtkWidget *child;
|
||||
ShaderInfo *active_shader;
|
||||
GPtrArray *shaders;
|
||||
guint tick_id;
|
||||
float time;
|
||||
float mouse_x, mouse_y;
|
||||
gint64 first_frame_time;
|
||||
};
|
||||
|
||||
struct _GtkShaderBinClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkShaderBin, gtk_shader_bin, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
shader_info_free (ShaderInfo *info)
|
||||
{
|
||||
g_object_unref (info->shader);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_bin_finalize (GObject *object)
|
||||
{
|
||||
GtkShaderBin *self = GTK_SHADER_BIN (object);
|
||||
|
||||
g_ptr_array_free (self->shaders, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_bin_dispose (GObject *object)
|
||||
{
|
||||
GtkShaderBin *self = GTK_SHADER_BIN (object);
|
||||
|
||||
g_clear_pointer (&self->child, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_shader_bin_tick (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkShaderBin *self = GTK_SHADER_BIN (widget);
|
||||
gint64 frame_time;
|
||||
|
||||
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
if (self->first_frame_time == 0)
|
||||
self->first_frame_time = frame_time;
|
||||
self->time = (frame_time - self->first_frame_time) / (float)G_USEC_PER_SEC;
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
motion_cb (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
GtkShaderBin *self)
|
||||
{
|
||||
self->mouse_x = x;
|
||||
self->mouse_y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_bin_init (GtkShaderBin *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
self->shaders = g_ptr_array_new_with_free_func ((GDestroyNotify)shader_info_free);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shader_bin_update_active_shader (GtkShaderBin *self)
|
||||
{
|
||||
GtkStateFlags new_state = gtk_widget_get_state_flags (GTK_WIDGET (self));
|
||||
ShaderInfo *new_shader = NULL;
|
||||
|
||||
for (int i = 0; i < self->shaders->len; i++)
|
||||
{
|
||||
ShaderInfo *info = g_ptr_array_index (self->shaders, i);
|
||||
|
||||
if ((info->state_mask & new_state) == info->state)
|
||||
{
|
||||
new_shader = info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (self->active_shader == new_shader)
|
||||
return;
|
||||
|
||||
self->active_shader = new_shader;
|
||||
self->first_frame_time = 0;
|
||||
|
||||
if (self->active_shader)
|
||||
{
|
||||
if (self->tick_id == 0)
|
||||
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
|
||||
gtk_shader_bin_tick,
|
||||
NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->tick_id != 0)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
|
||||
self->tick_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_bin_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state_flags)
|
||||
{
|
||||
GtkShaderBin *self = GTK_SHADER_BIN (widget);
|
||||
|
||||
gtk_shader_bin_update_active_shader (self);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shader_bin_add_shader (GtkShaderBin *self,
|
||||
GskGLShader *shader,
|
||||
GtkStateFlags state,
|
||||
GtkStateFlags state_mask,
|
||||
float extra_border)
|
||||
{
|
||||
ShaderInfo *info = g_new0 (ShaderInfo, 1);
|
||||
info->shader = g_object_ref (shader);
|
||||
info->state = state;
|
||||
info->state_mask = state_mask;
|
||||
info->extra_border = extra_border;
|
||||
|
||||
g_ptr_array_add (self->shaders, info);
|
||||
|
||||
gtk_shader_bin_update_active_shader (self);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shader_bin_set_child (GtkShaderBin *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
|
||||
if (self->child == child)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&self->child, gtk_widget_unparent);
|
||||
|
||||
if (child)
|
||||
{
|
||||
self->child = child;
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_shader_bin_get_child (GtkShaderBin *self)
|
||||
{
|
||||
return self->child;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_bin_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkShaderBin *self = GTK_SHADER_BIN (widget);
|
||||
int width, height;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
if (self->active_shader)
|
||||
{
|
||||
if (!self->active_shader->compiled)
|
||||
{
|
||||
GtkNative *native = gtk_widget_get_native (widget);
|
||||
GskRenderer *renderer = gtk_native_get_renderer (native);
|
||||
GError *error = NULL;
|
||||
|
||||
self->active_shader->compiled = TRUE;
|
||||
self->active_shader->compiled_ok =
|
||||
gsk_gl_shader_compile (self->active_shader->shader,
|
||||
renderer, &error);
|
||||
if (!self->active_shader->compiled_ok)
|
||||
{
|
||||
g_warning ("GtkShaderBin failed to compile shader: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
if (self->active_shader->compiled_ok)
|
||||
{
|
||||
float border = self->active_shader->extra_border;
|
||||
graphene_vec2_t mouse;
|
||||
graphene_vec2_init (&mouse, self->mouse_x + border, self->mouse_y + border);
|
||||
gtk_snapshot_push_gl_shader (snapshot, self->active_shader->shader,
|
||||
&GRAPHENE_RECT_INIT(-border, -border, width+2*border, height+2*border),
|
||||
gsk_gl_shader_format_args (self->active_shader->shader,
|
||||
"u_time", self->time,
|
||||
"u_mouse", &mouse,
|
||||
NULL));
|
||||
gtk_widget_snapshot_child (widget, self->child, snapshot);
|
||||
gtk_snapshot_gl_shader_pop_texture (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Non-shader fallback */
|
||||
gtk_widget_snapshot_child (widget, self->child, snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_bin_class_init (GtkShaderBinClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = gtk_shader_bin_finalize;
|
||||
object_class->dispose = gtk_shader_bin_dispose;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
widget_class->snapshot = gtk_shader_bin_snapshot;
|
||||
widget_class->state_flags_changed = gtk_shader_bin_state_flags_changed;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_shader_bin_new (void)
|
||||
{
|
||||
GtkShaderBin *self;
|
||||
|
||||
self = g_object_new (GTK_TYPE_SHADER_BIN, NULL);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SHADER_BIN (gtk_shader_bin_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkShaderBin, gtk_shader_bin, GTK, SHADER_BIN, GtkWidget)
|
||||
|
||||
GtkWidget *gtk_shader_bin_new (void);
|
||||
void gtk_shader_bin_add_shader (GtkShaderBin *self,
|
||||
GskGLShader *shader,
|
||||
GtkStateFlags state,
|
||||
GtkStateFlags state_mask,
|
||||
float extra_border);
|
||||
void gtk_shader_bin_set_child (GtkShaderBin *self,
|
||||
GtkWidget *child);
|
||||
GtkWidget *gtk_shader_bin_get_child (GtkShaderBin *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
@@ -1,365 +0,0 @@
|
||||
#include "gtkshaderstack.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
struct _GtkShaderStack
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GskGLShader *shader;
|
||||
GPtrArray *children;
|
||||
int current;
|
||||
int next;
|
||||
gboolean backwards;
|
||||
|
||||
guint tick_id;
|
||||
float time;
|
||||
float duration;
|
||||
gint64 start_time;
|
||||
};
|
||||
|
||||
struct _GtkShaderStackClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
PROP_DURATION = 1,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
|
||||
|
||||
G_DEFINE_TYPE (GtkShaderStack, gtk_shader_stack, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
gtk_shader_stack_finalize (GObject *object)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (object);
|
||||
|
||||
g_object_unref (self->shader);
|
||||
|
||||
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
update_child_visible (GtkShaderStack *self)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < self->children->len; i++)
|
||||
{
|
||||
GtkWidget *child = g_ptr_array_index (self->children, i);
|
||||
|
||||
gtk_widget_set_child_visible (child,
|
||||
i == self->current || i == self->next);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transition_cb (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (widget);
|
||||
gint64 frame_time;
|
||||
|
||||
frame_time = gdk_frame_clock_get_frame_time (clock);
|
||||
|
||||
if (self->start_time == 0)
|
||||
self->start_time = frame_time;
|
||||
|
||||
self->time = (frame_time - self->start_time) / (float)G_USEC_PER_SEC;
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
if (self->time >= self->duration)
|
||||
{
|
||||
self->current = self->next;
|
||||
self->next = -1;
|
||||
|
||||
update_child_visible (self);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
else
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_transition (GtkShaderStack *self)
|
||||
{
|
||||
self->start_time = 0;
|
||||
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
|
||||
transition_cb,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_transition (GtkShaderStack *self)
|
||||
{
|
||||
if (self->tick_id != 0)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
|
||||
self->tick_id = 0;
|
||||
}
|
||||
|
||||
if (self->next != -1)
|
||||
self->current = self->next;
|
||||
self->next = -1;
|
||||
|
||||
update_child_visible (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_dispose (GObject *object)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (object);
|
||||
|
||||
stop_transition (self);
|
||||
|
||||
g_clear_pointer (&self->children, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shader_stack_transition (GtkShaderStack *self,
|
||||
gboolean forward)
|
||||
{
|
||||
stop_transition (self);
|
||||
|
||||
self->backwards = !forward;
|
||||
if (self->backwards)
|
||||
self->next = (self->current + self->children->len - 1) % self->children->len;
|
||||
else
|
||||
self->next = (self->current + 1) % self->children->len;
|
||||
|
||||
update_child_visible (self);
|
||||
|
||||
start_transition (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_init (GtkShaderStack *self)
|
||||
{
|
||||
self->children = g_ptr_array_new_with_free_func ((GDestroyNotify)gtk_widget_unparent);
|
||||
self->current = -1;
|
||||
self->next = -1;
|
||||
self->backwards = FALSE;
|
||||
self->duration = 1.0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (widget);
|
||||
int i;
|
||||
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
|
||||
for (i = 0; i < self->children->len; i++)
|
||||
{
|
||||
GtkWidget *child = g_ptr_array_index (self->children, i);
|
||||
int child_min, child_nat;
|
||||
|
||||
if (gtk_widget_get_visible (child))
|
||||
{
|
||||
gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
|
||||
|
||||
*minimum = MAX (*minimum, child_min);
|
||||
*natural = MAX (*natural, child_nat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (widget);
|
||||
GtkAllocation child_allocation;
|
||||
GtkWidget *child;
|
||||
int i;
|
||||
|
||||
child_allocation.x = 0;
|
||||
child_allocation.y = 0;
|
||||
child_allocation.width = width;
|
||||
child_allocation.height = height;
|
||||
|
||||
for (i = 0; i < self->children->len; i++)
|
||||
{
|
||||
child = g_ptr_array_index (self->children, i);
|
||||
if (gtk_widget_get_visible (child))
|
||||
gtk_widget_size_allocate (child, &child_allocation, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (widget);
|
||||
int width, height;
|
||||
GtkWidget *current, *next;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
current = g_ptr_array_index (self->children, self->current);
|
||||
|
||||
if (self->next == -1)
|
||||
{
|
||||
gtk_widget_snapshot_child (widget, current, snapshot);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkNative *native = gtk_widget_get_native (widget);
|
||||
GskRenderer *renderer = gtk_native_get_renderer (native);
|
||||
float progress;
|
||||
|
||||
next = g_ptr_array_index (self->children, self->next);
|
||||
|
||||
progress = self->time / self->duration;
|
||||
|
||||
if (self->backwards)
|
||||
{
|
||||
GtkWidget *tmp = next;
|
||||
next = current;
|
||||
current = tmp;
|
||||
progress = 1. - progress;
|
||||
}
|
||||
|
||||
if (gsk_gl_shader_compile (self->shader, renderer, NULL))
|
||||
{
|
||||
gtk_snapshot_push_gl_shader (snapshot,
|
||||
self->shader,
|
||||
&GRAPHENE_RECT_INIT(0, 0, width, height),
|
||||
gsk_gl_shader_format_args (self->shader,
|
||||
"progress", progress,
|
||||
NULL));
|
||||
|
||||
gtk_widget_snapshot_child (widget, current, snapshot);
|
||||
gtk_snapshot_gl_shader_pop_texture (snapshot); /* current child */
|
||||
gtk_widget_snapshot_child (widget, next, snapshot);
|
||||
gtk_snapshot_gl_shader_pop_texture (snapshot); /* next child */
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non-shader fallback */
|
||||
gtk_widget_snapshot_child (widget, current, snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DURATION:
|
||||
g_value_set_float (value, self->duration);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkShaderStack *self = GTK_SHADER_STACK (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DURATION:
|
||||
self->duration = g_value_get_float (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shader_stack_class_init (GtkShaderStackClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = gtk_shader_stack_finalize;
|
||||
object_class->dispose = gtk_shader_stack_dispose;
|
||||
object_class->get_property = gtk_shader_stack_get_property;
|
||||
object_class->set_property = gtk_shader_stack_set_property;
|
||||
|
||||
widget_class->snapshot = gtk_shader_stack_snapshot;
|
||||
widget_class->measure = gtk_shader_stack_measure;
|
||||
widget_class->size_allocate = gtk_shader_stack_size_allocate;
|
||||
|
||||
properties[PROP_DURATION] =
|
||||
g_param_spec_float ("duration", "Duration", "Duration",
|
||||
0.1, 3.0, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_shader_stack_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_SHADER_STACK, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shader_stack_set_shader (GtkShaderStack *self,
|
||||
GskGLShader *shader)
|
||||
{
|
||||
g_set_object (&self->shader, shader);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shader_stack_add_child (GtkShaderStack *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
g_ptr_array_add (self->children, child);
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
|
||||
if (self->current == -1)
|
||||
self->current = 0;
|
||||
else
|
||||
gtk_widget_set_child_visible (child, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shader_stack_set_active (GtkShaderStack *self,
|
||||
int index)
|
||||
{
|
||||
stop_transition (self);
|
||||
self->current = MIN (index, self->children->len);
|
||||
update_child_visible (self);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SHADER_STACK (gtk_shader_stack_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkShaderStack, gtk_shader_stack, GTK, SHADER_STACK, GtkWidget)
|
||||
|
||||
GtkWidget * gtk_shader_stack_new (void);
|
||||
void gtk_shader_stack_set_shader (GtkShaderStack *self,
|
||||
GskGLShader *shader);
|
||||
void gtk_shader_stack_add_child (GtkShaderStack *self,
|
||||
GtkWidget *child);
|
||||
void gtk_shader_stack_transition (GtkShaderStack *self,
|
||||
gboolean forward);
|
||||
void gtk_shader_stack_set_active (GtkShaderStack *self,
|
||||
int index);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
typedef struct _GdkHSLA GdkHSLA;
|
||||
|
||||
struct _GdkHSLA {
|
||||
|
||||
+73
-29
@@ -13,7 +13,7 @@ static GtkWidget *window = NULL;
|
||||
static GtkWidget *scrolledwindow;
|
||||
static int selected;
|
||||
|
||||
#define N_WIDGET_TYPES 8
|
||||
#define N_WIDGET_TYPES 9
|
||||
|
||||
|
||||
static int hincrement = 5;
|
||||
@@ -73,30 +73,77 @@ populate_icons (void)
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), grid);
|
||||
}
|
||||
|
||||
static char *content;
|
||||
static gsize content_len;
|
||||
|
||||
extern void fontify (const char *format, GtkTextBuffer *buffer);
|
||||
|
||||
enum {
|
||||
PLAIN_TEXT,
|
||||
HIGHLIGHTED_TEXT,
|
||||
UNDERLINED_TEXT,
|
||||
};
|
||||
|
||||
static void
|
||||
populate_text (gboolean highlight)
|
||||
underlinify (GtkTextBuffer *buffer)
|
||||
{
|
||||
GtkTextTagTable *tags;
|
||||
GtkTextTag *tag[3];
|
||||
GtkTextIter start, end;
|
||||
|
||||
tags = gtk_text_buffer_get_tag_table (buffer);
|
||||
tag[0] = gtk_text_tag_new ("error");
|
||||
tag[1] = gtk_text_tag_new ("strikeout");
|
||||
tag[2] = gtk_text_tag_new ("double");
|
||||
g_object_set (tag[0], "underline", PANGO_UNDERLINE_ERROR, NULL);
|
||||
g_object_set (tag[1], "strikethrough", TRUE, NULL);
|
||||
g_object_set (tag[2],
|
||||
"underline", PANGO_UNDERLINE_DOUBLE,
|
||||
"underline-rgba", &(GdkRGBA){0., 1., 1., 1. },
|
||||
NULL);
|
||||
gtk_text_tag_table_add (tags, tag[0]);
|
||||
gtk_text_tag_table_add (tags, tag[1]);
|
||||
gtk_text_tag_table_add (tags, tag[2]);
|
||||
|
||||
gtk_text_buffer_get_start_iter (buffer, &end);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
start = end;
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
gtk_text_buffer_apply_tag (buffer, tag[g_random_int_range (0, 3)], &start, &end);
|
||||
if (!gtk_text_iter_forward_word_ends (&end, 3))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
populate_text (const char *resource, int kind)
|
||||
{
|
||||
GtkWidget *textview;
|
||||
GtkTextBuffer *buffer;
|
||||
char *content;
|
||||
gsize content_len;
|
||||
GBytes *bytes;
|
||||
|
||||
if (!content)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
|
||||
content = g_bytes_unref_to_data (bytes, &content_len);
|
||||
}
|
||||
bytes = g_resources_lookup_data (resource, 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 (highlight)
|
||||
fontify ("c", buffer);
|
||||
switch (kind)
|
||||
{
|
||||
case HIGHLIGHTED_TEXT:
|
||||
fontify ("c", buffer);
|
||||
break;
|
||||
|
||||
case UNDERLINED_TEXT:
|
||||
underlinify (buffer);
|
||||
break;
|
||||
|
||||
case PLAIN_TEXT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
textview = gtk_text_view_new ();
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
@@ -155,14 +202,6 @@ 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);
|
||||
|
||||
@@ -255,35 +294,40 @@ set_widget_type (int type)
|
||||
|
||||
case 1:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling plain text");
|
||||
populate_text (FALSE);
|
||||
populate_text ("/sources/font_features.c", PLAIN_TEXT);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling complex text");
|
||||
populate_text (TRUE);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling colored text");
|
||||
populate_text ("/sources/font_features.c", HIGHLIGHTED_TEXT);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with underlines");
|
||||
populate_text ("/org/gtk/Demo4/Moby-Dick.txt", UNDERLINED_TEXT);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with Emoji");
|
||||
populate_emoji_text ();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a big image");
|
||||
populate_image ();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 6:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a list");
|
||||
populate_list ();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 7:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a columned list");
|
||||
populate_list2 ();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 8:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a grid");
|
||||
populate_grid ();
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="resizable">0</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="default-width">500</property>
|
||||
<property name="default-height">500</property>
|
||||
<child type="titlebar">
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
uniform float progress;
|
||||
uniform sampler2D u_texture1;
|
||||
uniform sampler2D u_texture2;
|
||||
|
||||
vec4 getFromColor (vec2 uv) {
|
||||
return GskTexture(u_texture1, uv);
|
||||
}
|
||||
|
||||
vec4 getToColor (vec2 uv) {
|
||||
return GskTexture(u_texture2, uv);
|
||||
}
|
||||
|
||||
// Source: https://gl-transitions.com/editor/kaleidoscope
|
||||
// Author: nwoeanhinnogaehr
|
||||
// License: MIT
|
||||
|
||||
const float speed = 1.0;
|
||||
const float angle = 1.0;
|
||||
const float power = 1.5;
|
||||
|
||||
vec4 transition(vec2 uv) {
|
||||
vec2 p = uv.xy / vec2(1.0).xy;
|
||||
vec2 q = p;
|
||||
float t = pow(progress, power)*speed;
|
||||
p = p -0.5;
|
||||
for (int i = 0; i < 7; i++) {
|
||||
p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);
|
||||
t += angle;
|
||||
p = abs(mod(p, 2.0) - 1.0);
|
||||
}
|
||||
abs(mod(p, 1.0));
|
||||
return mix(
|
||||
mix(getFromColor(q), getToColor(q), progress),
|
||||
mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));
|
||||
}
|
||||
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||
{
|
||||
fragColor = transition(uv);
|
||||
}
|
||||
@@ -355,28 +355,28 @@ create_clocks_model (void)
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
/* A bunch of timezones with GTK hackers */
|
||||
clock = gtk_clock_new ("San Francisco", g_time_zone_new ("America/Los_Angeles"));
|
||||
clock = gtk_clock_new ("San Francisco", g_time_zone_new_identifier ("America/Los_Angeles"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("Xalapa", g_time_zone_new ("America/Mexico_City"));
|
||||
clock = gtk_clock_new ("Xalapa", g_time_zone_new_identifier ("America/Mexico_City"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("Boston", g_time_zone_new ("America/New_York"));
|
||||
clock = gtk_clock_new ("Boston", g_time_zone_new_identifier ("America/New_York"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("London", g_time_zone_new ("Europe/London"));
|
||||
clock = gtk_clock_new ("London", g_time_zone_new_identifier ("Europe/London"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("Berlin", g_time_zone_new ("Europe/Berlin"));
|
||||
clock = gtk_clock_new ("Berlin", g_time_zone_new_identifier ("Europe/Berlin"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("Moscow", g_time_zone_new ("Europe/Moscow"));
|
||||
clock = gtk_clock_new ("Moscow", g_time_zone_new_identifier ("Europe/Moscow"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("New Delhi", g_time_zone_new ("Asia/Kolkata"));
|
||||
clock = gtk_clock_new ("New Delhi", g_time_zone_new_identifier ("Asia/Kolkata"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("Shanghai", g_time_zone_new ("Asia/Shanghai"));
|
||||
clock = gtk_clock_new ("Shanghai", g_time_zone_new_identifier ("Asia/Shanghai"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
|
||||
|
||||
@@ -156,11 +156,6 @@ gtk_demo_run (GtkDemo *self,
|
||||
if (result == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (GTK_IS_WINDOW (result))
|
||||
{
|
||||
gtk_window_set_transient_for (GTK_WINDOW (result), GTK_WINDOW (window));
|
||||
gtk_window_set_modal (GTK_WINDOW (result), TRUE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -832,9 +827,6 @@ static gboolean
|
||||
demo_can_run (GtkWidget *window,
|
||||
const char *name)
|
||||
{
|
||||
if (name != NULL && strcmp (name, "gltransition") == 0)
|
||||
return GSK_IS_GL_RENDERER (gtk_native_get_renderer (GTK_NATIVE (window)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ demos = files([
|
||||
'gears.c',
|
||||
'gestures.c',
|
||||
'glarea.c',
|
||||
'gltransition.c',
|
||||
'headerbar.c',
|
||||
'hypertext.c',
|
||||
'iconscroll.c',
|
||||
@@ -117,10 +116,7 @@ extra_demo_sources = files([
|
||||
'gtkfishbowl.c',
|
||||
'fontplane.c',
|
||||
'gtkgears.c',
|
||||
'gtkshaderbin.c',
|
||||
'gtkshadertoy.c',
|
||||
'gtkshaderstack.c',
|
||||
'gskshaderpaintable.c',
|
||||
'hsla.c',
|
||||
'puzzlepiece.c',
|
||||
'bluroverlay.c',
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
#define NODE_TYPE_WIDGET (node_widget_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
|
||||
|
||||
GtkWidget * node_widget_new (const char *file);
|
||||
GtkWidget * node_widget_new (const char *resource);
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
uniform float progress;
|
||||
uniform sampler2D u_texture1;
|
||||
uniform sampler2D u_texture2;
|
||||
|
||||
vec4 getFromColor (vec2 uv) {
|
||||
return GskTexture(u_texture1, uv);
|
||||
}
|
||||
|
||||
vec4 getToColor (vec2 uv) {
|
||||
return GskTexture(u_texture2, uv);
|
||||
}
|
||||
|
||||
// Source: https://gl-transitions.com/editor/Radial
|
||||
// License: MIT
|
||||
// Author: Xaychru
|
||||
|
||||
const float smoothness = 1.0;
|
||||
|
||||
const float PI = 3.141592653589;
|
||||
|
||||
vec4 transition(vec2 p) {
|
||||
vec2 rp = p*2.-1.;
|
||||
return mix(
|
||||
getToColor(p),
|
||||
getFromColor(p),
|
||||
smoothstep(0., smoothness, atan(rp.y,rp.x) - (progress-.5) * PI * 2.5)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||
{
|
||||
fragColor = transition(uv);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
uniform float u_time;
|
||||
uniform vec2 u_mouse;
|
||||
uniform sampler2D u_texture1;
|
||||
|
||||
#define PI 3.141592654
|
||||
|
||||
float decay(float v, float t)
|
||||
{
|
||||
return v * (1.0 / (1.0 + t*t));
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||
{
|
||||
// Temporary to loop time every 1 sec
|
||||
float time = u_time;
|
||||
// we normalize all the effects according to the min height/width
|
||||
float size = min(resolution.x, resolution.y);
|
||||
|
||||
// Animate one wave over size in 0.3 sec
|
||||
float wave_speed = size / 0.3;
|
||||
float wave_length = size / 1.0;
|
||||
float wave_height = size * 0.1;
|
||||
|
||||
vec2 center = u_mouse;
|
||||
vec2 direction_from_center = fragCoord - center;
|
||||
float distance_from_center = length(direction_from_center);
|
||||
|
||||
/* Normalize direction */
|
||||
direction_from_center = direction_from_center / distance_from_center;
|
||||
|
||||
float propagation_length = time * wave_speed;
|
||||
|
||||
float t = (propagation_length - distance_from_center) / wave_length;
|
||||
float offset_magnitude = 0.0;
|
||||
if (t > 0.0)
|
||||
offset_magnitude = decay(wave_height * sin(t * 2.0 * PI), t);
|
||||
|
||||
vec2 offset = direction_from_center * min(offset_magnitude, distance_from_center);
|
||||
vec2 source = fragCoord - offset;
|
||||
|
||||
vec2 uv2 = source / resolution;
|
||||
fragColor = GskTexture(u_texture1, vec2(uv2.x, 1.0-uv2.y));
|
||||
}
|
||||
@@ -43,7 +43,7 @@ GtkListItemFactory *
|
||||
suggestion_entry_get_factory (SuggestionEntry *self);
|
||||
|
||||
void suggestion_entry_set_use_filter (SuggestionEntry *self,
|
||||
gboolean use_ilter);
|
||||
gboolean use_filter);
|
||||
gboolean suggestion_entry_get_use_filter (SuggestionEntry *self);
|
||||
|
||||
void suggestion_entry_set_expression (SuggestionEntry *self,
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
uniform float progress;
|
||||
uniform sampler2D u_texture1;
|
||||
uniform sampler2D u_texture2;
|
||||
|
||||
vec4 getFromColor (vec2 uv) {
|
||||
return GskTexture(u_texture1, uv);
|
||||
}
|
||||
|
||||
vec4 getToColor (vec2 uv) {
|
||||
return GskTexture(u_texture2, uv);
|
||||
}
|
||||
|
||||
// Source: https://gl-transitions.com/editor/wind
|
||||
// Author: gre
|
||||
// License: MIT
|
||||
|
||||
const float size = 0.2;
|
||||
|
||||
float rand(vec2 co) {
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
vec4 transition(vec2 p) {
|
||||
float r = rand(vec2(0, p.y));
|
||||
float m = smoothstep(0.0, -size, p.x*(1.0-size) + size*r - (progress * (1.0 + size)));
|
||||
return mix(getFromColor(p), getToColor(p), m);
|
||||
}
|
||||
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||
{
|
||||
fragColor = transition(uv);
|
||||
}
|
||||
@@ -925,7 +925,7 @@ export_image_response_cb (GObject *source,
|
||||
GdkTexture *texture;
|
||||
GskRenderer *renderer;
|
||||
|
||||
renderer = gsk_gl_renderer_new ();
|
||||
renderer = gsk_ngl_renderer_new ();
|
||||
if (!gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), NULL))
|
||||
{
|
||||
g_object_unref (renderer);
|
||||
|
||||
@@ -66,10 +66,6 @@ You can compile the program above with GCC using:
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
|
||||
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
|
||||
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
|
||||
others in this documentation.
|
||||
For more information on how to compile a GTK application, please
|
||||
refer to the [Compiling GTK Applications](compiling.html)
|
||||
section in this reference.
|
||||
|
||||
@@ -181,15 +181,21 @@ matrix3d() production to specify all 16 values individually.
|
||||
|
||||
### conic-gradient
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| center | `<point>` | 25, 25 | always |
|
||||
| rotation | `<number>` | 0 | always |
|
||||
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
|
||||
| property | syntax | default | printed |
|
||||
| ----------------- | --------------- | -------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| center | `<point>` | 25, 25 | always |
|
||||
| rotation | `<number>` | 0 | always |
|
||||
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
|
||||
| interpolation | `<color-state>` | srgb | non-default |
|
||||
| hue-interpolation | `<hue-interp>` | shorter | non-default |
|
||||
|
||||
Creates a node like `gsk_conic_gradient_node_new()` with the given properties.
|
||||
|
||||
Possible values for the hue-interpolation property are:
|
||||
|
||||
hue-interpolation: shorter | longer | increasing | decreasing
|
||||
|
||||
### cross-fade
|
||||
|
||||
| property | syntax | default | printed |
|
||||
@@ -258,12 +264,14 @@ Creates a node like `gsk_inset_shadow_node_new()` with the given properties.
|
||||
|
||||
### linear-gradient
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| start | `<point>` | 0 0 | always |
|
||||
| end | `<point>` | 0 50 | always |
|
||||
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
|
||||
| property | syntax | default | printed |
|
||||
| ----------------- | --------------- | -------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| start | `<point>` | 0 0 | always |
|
||||
| end | `<point>` | 0 50 | always |
|
||||
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
|
||||
| interpolation | `<color-state>` | srgb | non-default |
|
||||
| hue-interpolation | `<hue-interp>` | shorter | non-default |
|
||||
|
||||
Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
|
||||
|
||||
@@ -305,15 +313,17 @@ Creates a node like `gsk_outset_shadow_node_new()` with the given properties.
|
||||
|
||||
### radial-gradient
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| center | `<point>` | 25 25 | always |
|
||||
| hradius | `<number>` | 25 | always |
|
||||
| vradius | `<number>` | 25 | always |
|
||||
| start | `<number>` | 0 | always |
|
||||
| end | `<number>` | 1 | always |
|
||||
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
|
||||
| property | syntax | default | printed |
|
||||
| ----------------- | --------------- | -------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| center | `<point>` | 25 25 | always |
|
||||
| hradius | `<number>` | 25 | always |
|
||||
| vradius | `<number>` | 25 | always |
|
||||
| start | `<number>` | 0 | always |
|
||||
| end | `<number>` | 1 | always |
|
||||
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
|
||||
| interpolation | `<color-state>` | srgb | non-default |
|
||||
| hue-interpolation | `<hue-interp>` | shorter | non-default |
|
||||
|
||||
Creates a node like `gsk_radial_gradient_node_new()` with the given properties.
|
||||
|
||||
|
||||
@@ -380,13 +380,6 @@ does not support them.
|
||||
`base-instance`
|
||||
:GL_EXT_base_instance
|
||||
|
||||
### `GDK_VULKAN_DEVICE`
|
||||
|
||||
This variable can be set to the index of a Vulkan device to override
|
||||
the default selection of the device that is used for Vulkan rendering.
|
||||
The special value `list` can be used to obtain a list of all Vulkan
|
||||
devices.
|
||||
|
||||
### `GDK_VULKAN_DISABLE`
|
||||
|
||||
This variable can be set to a list of values, which cause GDK to
|
||||
@@ -430,14 +423,8 @@ using and the GDK backend supports them:
|
||||
`cairo`
|
||||
: Selects the fallback Cairo renderer
|
||||
|
||||
`opengl`
|
||||
: Selects the default OpenGL renderer
|
||||
|
||||
`gl`
|
||||
: Selects the "gl" OpenGL renderer
|
||||
|
||||
`ngl`
|
||||
: Selects the "ngl" OpenGL renderer
|
||||
: Selects the OpenGL renderer
|
||||
|
||||
`vulkan`
|
||||
: Selects the Vulkan renderer
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ main (int argc,
|
||||
g_chdir (GTK_SRCDIR);
|
||||
#endif
|
||||
|
||||
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
|
||||
int status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
|
||||
@@ -60,7 +60,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
|
||||
@@ -37,10 +37,8 @@ main (int argc,
|
||||
{
|
||||
GtkApplication *app;
|
||||
|
||||
app = gtk_application_new ("org.gtk.Example.GtkSearchBar",
|
||||
G_APPLICATION_FLAGS_NONE);
|
||||
g_signal_connect (app, "activate",
|
||||
G_CALLBACK (activate_cb), NULL);
|
||||
app = gtk_application_new ("org.gtk.Example.GtkSearchBar", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate_cb), NULL);
|
||||
|
||||
return g_application_run (G_APPLICATION (app), argc, argv);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
|
||||
@@ -111,7 +111,7 @@ gboolean broadway_server_surface_translate (BroadwayServer *
|
||||
int dx,
|
||||
int dy);
|
||||
guint32 broadway_server_upload_texture (BroadwayServer *server,
|
||||
GBytes *texture);
|
||||
GBytes *bytes);
|
||||
void broadway_server_release_texture (BroadwayServer *server,
|
||||
guint32 id);
|
||||
cairo_surface_t * broadway_server_create_surface (int width,
|
||||
|
||||
@@ -257,6 +257,12 @@ gdk_broadway_display_flush (GdkDisplay *display)
|
||||
_gdk_broadway_server_flush (broadway_display->server);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_broadway_display_has_pending (GdkDisplay *display)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_display_dispose (GObject *object)
|
||||
{
|
||||
@@ -479,6 +485,7 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
|
||||
display_class->beep = gdk_broadway_display_beep;
|
||||
display_class->sync = gdk_broadway_display_sync;
|
||||
display_class->flush = gdk_broadway_display_flush;
|
||||
display_class->has_pending = gdk_broadway_display_has_pending;
|
||||
display_class->queue_events = _gdk_broadway_display_queue_events;
|
||||
|
||||
display_class->get_next_serial = gdk_broadway_display_get_next_serial;
|
||||
|
||||
@@ -56,7 +56,7 @@ void _gdk_broadway_surface_translate (GdkSurface *surface,
|
||||
int dx,
|
||||
int dy);
|
||||
gboolean _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
|
||||
BroadwayInputMsg *msg);
|
||||
BroadwayInputMsg *event);
|
||||
gboolean _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
void _gdk_broadway_roundtrip_notify (GdkSurface *surface,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
void file_transfer_portal_register (void);
|
||||
|
||||
|
||||
@@ -122,6 +122,18 @@ gdk_cairo_pattern_add_color_stop_rgba_ccs (cairo_pattern_t *pattern,
|
||||
cairo_pattern_add_color_stop_rgba (pattern, offset, color[0], color[1], color[2], color[3]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_cairo_pattern_add_color_stop_color (cairo_pattern_t *pattern,
|
||||
GdkColorState *ccs,
|
||||
double offset,
|
||||
const GdkColor *color)
|
||||
{
|
||||
float values[4];
|
||||
|
||||
gdk_color_to_float (color, ccs, values);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, offset, values[0], values[1], values[2], values[3]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_cairo_rect (cairo_t *cr,
|
||||
const graphene_rect_t *rect)
|
||||
|
||||
@@ -79,6 +79,6 @@ gdk_cicp_equivalent (const GdkCicp *p1,
|
||||
return gdk_cicp_equal (&n1, &n2);
|
||||
}
|
||||
|
||||
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *params);
|
||||
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *self);
|
||||
|
||||
GdkCicpParams * gdk_cicp_params_new_for_cicp (const GdkCicp *cicp);
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
* and tests, and must not include other headers.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <math.h>
|
||||
|
||||
static inline int
|
||||
sign (float v)
|
||||
{
|
||||
@@ -230,3 +233,53 @@ static const float srgb_to_rec2020[9] = {
|
||||
0.069108, 0.919519, 0.011360,
|
||||
0.016394, 0.088011, 0.895380,
|
||||
};
|
||||
|
||||
/* oklab conversion */
|
||||
|
||||
static float
|
||||
from_oklab_nl (float v)
|
||||
{
|
||||
return v * v * v;
|
||||
}
|
||||
|
||||
static float
|
||||
to_oklab_nl (float v)
|
||||
{
|
||||
return cbrtf (v);
|
||||
}
|
||||
|
||||
static const float oklab_to_lms[9] = {
|
||||
1, 0.3963377774, 0.2158037573,
|
||||
1, -0.1055613458, -0.0638541728,
|
||||
1, -0.0894841775, -1.2914855480
|
||||
};
|
||||
|
||||
static const float lms_to_srgb[9] = {
|
||||
4.0767416621, -3.3077115913, 0.2309699292,
|
||||
-1.2684380046, 2.6097574011, -0.3413193965,
|
||||
-0.0041960863, -0.7034186147, 1.7076147010,
|
||||
};
|
||||
|
||||
static const float srgb_to_lms[9] = {
|
||||
0.4122214708, 0.5363325363, 0.0514459929,
|
||||
0.2119034982, 0.6806995451, 0.1073969566,
|
||||
0.0883024619, 0.2817188376, 0.6299787005,
|
||||
};
|
||||
|
||||
static const float lms_to_oklab[9] = {
|
||||
0.2104542553, 0.7936177850, -0.0040720468,
|
||||
1.9779984951, -2.4285922050, 0.4505937099,
|
||||
0.0259040371, 0.7827717662, -0.8086757660,
|
||||
};
|
||||
|
||||
static const float rec2020_to_lms[9] = {
|
||||
0.616645, 0.360250, 0.023064,
|
||||
0.265075, 0.635874, 0.099059,
|
||||
0.100076, 0.203907, 0.696161,
|
||||
};
|
||||
|
||||
static const float lms_to_rec2020[9] = {
|
||||
2.140325, -1.246734, 0.106491,
|
||||
-0.884665, 2.163141, -0.278489,
|
||||
-0.048559, -0.454366, 1.502711,
|
||||
};
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdkcolorprivate.h"
|
||||
|
||||
#include "gdkcolorstateprivate.h"
|
||||
|
||||
|
||||
|
||||
@@ -79,8 +79,8 @@ void gdk_color_init_from_rgba (GdkColor *self,
|
||||
const GdkRGBA *rgba);
|
||||
void gdk_color_finish (GdkColor *self);
|
||||
|
||||
gboolean gdk_color_equal (const GdkColor *color1,
|
||||
const GdkColor *color2);
|
||||
gboolean gdk_color_equal (const GdkColor *self,
|
||||
const GdkColor *other);
|
||||
gboolean gdk_color_is_clear (const GdkColor *self);
|
||||
gboolean gdk_color_is_opaque (const GdkColor *self);
|
||||
|
||||
|
||||
+254
-67
@@ -172,6 +172,18 @@ gdk_color_state_get_rec2100_linear (void)
|
||||
return GDK_COLOR_STATE_REC2100_LINEAR;
|
||||
}
|
||||
|
||||
GdkColorState *
|
||||
gdk_color_state_get_oklab (void)
|
||||
{
|
||||
return GDK_COLOR_STATE_OKLAB;
|
||||
}
|
||||
|
||||
GdkColorState *
|
||||
gdk_color_state_get_oklch (void)
|
||||
{
|
||||
return GDK_COLOR_STATE_OKLCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_color_state_equal:
|
||||
* @self: a `GdkColorState`
|
||||
@@ -223,56 +235,171 @@ gdk_color_state_create_cicp_params (GdkColorState *self)
|
||||
/* {{{ Conversion functions */
|
||||
|
||||
typedef float (* GdkTransferFunc) (float v);
|
||||
typedef void (* GdkConvertFunc) (GdkColorState *self,
|
||||
float values[4]);
|
||||
typedef const float GdkColorMatrix[9];
|
||||
|
||||
#define IDENTITY ((float*)0)
|
||||
#define NONE ((GdkTransferFunc)0)
|
||||
|
||||
#define TRANSFORM(name, eotf, matrix, oetf) \
|
||||
#define CONVERT_FUNC(name) \
|
||||
static void \
|
||||
name (GdkColorState *self, \
|
||||
float (*values)[4], \
|
||||
gsize n_values) \
|
||||
gdk_convert_ ## name (GdkColorState *self, \
|
||||
float (*values)[4], \
|
||||
gsize n_values) \
|
||||
{ \
|
||||
for (gsize i = 0; i < n_values; i++) \
|
||||
{ \
|
||||
if (eotf != NONE) \
|
||||
{ \
|
||||
values[i][0] = eotf (values[i][0]); \
|
||||
values[i][1] = eotf (values[i][1]); \
|
||||
values[i][2] = eotf (values[i][2]); \
|
||||
} \
|
||||
if (matrix != IDENTITY) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
res[0] = matrix[0] * values[i][0] + matrix[1] * values[i][1] + matrix[2] * values[i][2]; \
|
||||
res[1] = matrix[3] * values[i][0] + matrix[4] * values[i][1] + matrix[5] * values[i][2]; \
|
||||
res[2] = matrix[6] * values[i][0] + matrix[7] * values[i][1] + matrix[8] * values[i][2]; \
|
||||
values[i][0] = res[0]; \
|
||||
values[i][1] = res[1]; \
|
||||
values[i][2] = res[2]; \
|
||||
} \
|
||||
if (oetf != NONE) \
|
||||
{ \
|
||||
values[i][0] = oetf (values[i][0]); \
|
||||
values[i][1] = oetf (values[i][1]); \
|
||||
values[i][2] = oetf (values[i][2]); \
|
||||
} \
|
||||
name (self, values[i]); \
|
||||
} \
|
||||
}
|
||||
|
||||
TRANSFORM(gdk_default_srgb_to_srgb_linear, srgb_eotf, IDENTITY, NONE);
|
||||
TRANSFORM(gdk_default_srgb_linear_to_srgb, NONE, IDENTITY, srgb_oetf)
|
||||
TRANSFORM(gdk_default_rec2100_pq_to_rec2100_linear, pq_eotf, IDENTITY, NONE)
|
||||
TRANSFORM(gdk_default_rec2100_linear_to_rec2100_pq, NONE, IDENTITY, pq_oetf)
|
||||
TRANSFORM(gdk_default_srgb_linear_to_rec2100_linear, NONE, srgb_to_rec2020, NONE)
|
||||
TRANSFORM(gdk_default_rec2100_linear_to_srgb_linear, NONE, rec2020_to_srgb, NONE)
|
||||
TRANSFORM(gdk_default_srgb_to_rec2100_linear, srgb_eotf, srgb_to_rec2020, NONE)
|
||||
TRANSFORM(gdk_default_rec2100_pq_to_srgb_linear, pq_eotf, rec2020_to_srgb, NONE)
|
||||
TRANSFORM(gdk_default_srgb_linear_to_rec2100_pq, NONE, srgb_to_rec2020, pq_oetf)
|
||||
TRANSFORM(gdk_default_rec2100_linear_to_srgb, NONE, rec2020_to_srgb, srgb_oetf)
|
||||
TRANSFORM(gdk_default_srgb_to_rec2100_pq, srgb_eotf, srgb_to_rec2020, pq_oetf)
|
||||
TRANSFORM(gdk_default_rec2100_pq_to_srgb, pq_eotf, rec2020_to_srgb, srgb_oetf)
|
||||
#define TRANSFORM(name, eotf, matrix, nonlinear, matrix2, oetf) \
|
||||
static inline void \
|
||||
name (GdkColorState *self, \
|
||||
float values[4]) \
|
||||
{ \
|
||||
if (eotf != NONE) \
|
||||
{ \
|
||||
values[0] = eotf (values[0]); \
|
||||
values[1] = eotf (values[1]); \
|
||||
values[2] = eotf (values[2]); \
|
||||
} \
|
||||
if (matrix != IDENTITY) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
res[0] = matrix[0] * values[0] + matrix[1] * values[1] + matrix[2] * values[2]; \
|
||||
res[1] = matrix[3] * values[0] + matrix[4] * values[1] + matrix[5] * values[2]; \
|
||||
res[2] = matrix[6] * values[0] + matrix[7] * values[1] + matrix[8] * values[2]; \
|
||||
values[0] = res[0]; \
|
||||
values[1] = res[1]; \
|
||||
values[2] = res[2]; \
|
||||
} \
|
||||
if (nonlinear != NONE) \
|
||||
{ \
|
||||
values[0] = nonlinear (values[0]); \
|
||||
values[1] = nonlinear (values[1]); \
|
||||
values[2] = nonlinear (values[2]); \
|
||||
} \
|
||||
if (matrix2 != IDENTITY) \
|
||||
{ \
|
||||
float res[3]; \
|
||||
res[0] = matrix2[0] * values[0] + matrix2[1] * values[1] + matrix2[2] * values[2]; \
|
||||
res[1] = matrix2[3] * values[0] + matrix2[4] * values[1] + matrix2[5] * values[2]; \
|
||||
res[2] = matrix2[6] * values[0] + matrix2[7] * values[1] + matrix2[8] * values[2]; \
|
||||
values[0] = res[0]; \
|
||||
values[1] = res[1]; \
|
||||
values[2] = res[2]; \
|
||||
} \
|
||||
if (oetf != NONE) \
|
||||
{ \
|
||||
values[0] = oetf (values[0]); \
|
||||
values[1] = oetf (values[1]); \
|
||||
values[2] = oetf (values[2]); \
|
||||
} \
|
||||
} \
|
||||
CONVERT_FUNC (name)
|
||||
|
||||
#define TRANSFORM_PAIR(name, func1, func2) \
|
||||
static inline void \
|
||||
name (GdkColorState *self, \
|
||||
float values[4]) \
|
||||
{ \
|
||||
func1 (self, values); \
|
||||
func2 (self, values); \
|
||||
} \
|
||||
CONVERT_FUNC (name)
|
||||
|
||||
TRANSFORM(srgb_to_srgb_linear, srgb_eotf, IDENTITY, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(srgb_linear_to_srgb, NONE, IDENTITY, NONE, IDENTITY, srgb_oetf)
|
||||
TRANSFORM(rec2100_pq_to_rec2100_linear, pq_eotf, IDENTITY, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(rec2100_linear_to_rec2100_pq, NONE, IDENTITY, NONE, IDENTITY, pq_oetf)
|
||||
TRANSFORM(srgb_linear_to_rec2100_linear, NONE, srgb_to_rec2020, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(rec2100_linear_to_srgb_linear, NONE, rec2020_to_srgb, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(srgb_to_rec2100_linear, srgb_eotf, srgb_to_rec2020, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(rec2100_pq_to_srgb_linear, pq_eotf, rec2020_to_srgb, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(srgb_linear_to_rec2100_pq, NONE, srgb_to_rec2020, NONE, IDENTITY, pq_oetf)
|
||||
TRANSFORM(rec2100_linear_to_srgb, NONE, rec2020_to_srgb, NONE, IDENTITY, srgb_oetf)
|
||||
TRANSFORM(srgb_to_rec2100_pq, srgb_eotf, srgb_to_rec2020, NONE, IDENTITY, pq_oetf)
|
||||
TRANSFORM(rec2100_pq_to_srgb, pq_eotf, rec2020_to_srgb, NONE, IDENTITY, srgb_oetf)
|
||||
|
||||
TRANSFORM(oklab_to_srgb_linear, NONE, oklab_to_lms, from_oklab_nl, lms_to_srgb, NONE)
|
||||
TRANSFORM(oklab_to_srgb, NONE, oklab_to_lms, from_oklab_nl, lms_to_srgb, srgb_oetf)
|
||||
TRANSFORM(oklab_to_rec2100_linear, NONE, oklab_to_lms, from_oklab_nl, lms_to_rec2020, NONE)
|
||||
TRANSFORM(oklab_to_rec2100_pq, NONE, oklab_to_lms, from_oklab_nl, lms_to_rec2020, pq_oetf)
|
||||
TRANSFORM(srgb_linear_to_oklab, NONE, srgb_to_lms, to_oklab_nl, lms_to_oklab, NONE)
|
||||
TRANSFORM(srgb_to_oklab, srgb_eotf, srgb_to_lms, to_oklab_nl, lms_to_oklab, NONE)
|
||||
TRANSFORM(rec2100_linear_to_oklab, NONE, rec2020_to_lms, to_oklab_nl, lms_to_oklab, NONE)
|
||||
TRANSFORM(rec2100_pq_to_oklab, pq_eotf, rec2020_to_lms, to_oklab_nl, lms_to_oklab, NONE)
|
||||
|
||||
#define DEG_TO_RAD(x) ((x) * G_PI / 180)
|
||||
#define RAD_TO_DEG(x) ((x) * 180 / G_PI)
|
||||
|
||||
static inline void
|
||||
_sincosf (float angle,
|
||||
float *out_s,
|
||||
float *out_c)
|
||||
{
|
||||
#ifdef HAVE_SINCOSF
|
||||
sincosf (angle, out_s, out_c);
|
||||
#else
|
||||
*out_s = sinf (angle);
|
||||
*out_c = cosf (angle);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
oklch_to_oklab (GdkColorState *self,
|
||||
float values[4])
|
||||
{
|
||||
float L, C, H, a, b;
|
||||
|
||||
L = values[0];
|
||||
C = values[1];
|
||||
H = values[2];
|
||||
|
||||
_sincosf (DEG_TO_RAD (H), &b, &a);
|
||||
a *= C;
|
||||
b *= C;
|
||||
|
||||
values[0] = L;
|
||||
values[1] = a;
|
||||
values[2] = b;
|
||||
}
|
||||
|
||||
static void
|
||||
oklab_to_oklch (GdkColorState *self,
|
||||
float values[4])
|
||||
{
|
||||
float L, a, b, C, H;
|
||||
|
||||
L = values[0];
|
||||
a = values[1];
|
||||
b = values[2];
|
||||
|
||||
C = hypotf (a, b);
|
||||
H = RAD_TO_DEG (atan2 (b, a));
|
||||
|
||||
H = fmod (H, 360);
|
||||
if (H < 0)
|
||||
H += 360;
|
||||
|
||||
values[0] = L;
|
||||
values[1] = C;
|
||||
values[2] = H;
|
||||
}
|
||||
|
||||
CONVERT_FUNC (oklch_to_oklab)
|
||||
CONVERT_FUNC (oklab_to_oklch)
|
||||
|
||||
TRANSFORM_PAIR (srgb_to_oklch, srgb_to_oklab, oklab_to_oklch)
|
||||
TRANSFORM_PAIR (srgb_linear_to_oklch, srgb_linear_to_oklab, oklab_to_oklch)
|
||||
TRANSFORM_PAIR (rec2100_pq_to_oklch, rec2100_pq_to_oklab, oklab_to_oklch)
|
||||
TRANSFORM_PAIR (rec2100_linear_to_oklch, rec2100_linear_to_oklab, oklab_to_oklch)
|
||||
TRANSFORM_PAIR (oklch_to_srgb, oklch_to_oklab, oklab_to_srgb)
|
||||
TRANSFORM_PAIR (oklch_to_srgb_linear, oklch_to_oklab, oklab_to_srgb_linear)
|
||||
TRANSFORM_PAIR (oklch_to_rec2100_pq, oklch_to_oklab, oklab_to_rec2100_pq)
|
||||
TRANSFORM_PAIR (oklch_to_rec2100_linear, oklch_to_oklab, oklab_to_rec2100_pq)
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Default implementation */
|
||||
@@ -328,6 +455,9 @@ gdk_default_color_state_get_cicp (GdkColorState *color_state)
|
||||
{
|
||||
GdkDefaultColorState *self = (GdkDefaultColorState *) color_state;
|
||||
|
||||
if (self->cicp.color_primaries == 0)
|
||||
return NULL;
|
||||
|
||||
return &self->cicp;
|
||||
}
|
||||
|
||||
@@ -419,9 +549,11 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
.name = "srgb",
|
||||
.no_srgb = GDK_COLOR_STATE_SRGB_LINEAR,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_srgb_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_srgb_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_srgb_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_srgb_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_srgb_to_oklab,
|
||||
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_srgb_to_oklch,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_0_1,
|
||||
.cicp = { 1, 13, 0, 1 },
|
||||
@@ -437,9 +569,11 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
.name = "srgb-linear",
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_srgb_linear_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_linear_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_linear_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_srgb_linear_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_srgb_linear_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_srgb_linear_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_srgb_linear_to_oklab,
|
||||
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_srgb_linear_to_oklch,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_0_1,
|
||||
.cicp = { 1, 8, 0, 1 },
|
||||
@@ -455,9 +589,11 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
.name = "rec2100-pq",
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_pq_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_pq_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_rec2100_pq_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_rec2100_pq_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_rec2100_pq_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_rec2100_pq_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_rec2100_pq_to_oklab,
|
||||
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_rec2100_pq_to_oklch,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_0_1,
|
||||
.cicp = { 9, 16, 0, 1 },
|
||||
@@ -473,16 +609,54 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
.name = "rec2100-linear",
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_linear_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_linear_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_rec2100_linear_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_rec2100_linear_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_rec2100_linear_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_rec2100_linear_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_rec2100_linear_to_oklab,
|
||||
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_rec2100_linear_to_oklch,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_unbounded,
|
||||
.cicp = { 9, 8, 0, 1 },
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_OKLAB] = {
|
||||
.parent = {
|
||||
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
|
||||
.ref_count = 0,
|
||||
.depth = GDK_MEMORY_FLOAT16,
|
||||
.rendering_color_state = GDK_COLOR_STATE_SRGB,
|
||||
},
|
||||
.name = "oklab",
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_oklab_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_oklab_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_oklab_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_oklab_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_oklab_to_oklch,
|
||||
},
|
||||
.cicp = { 0, 0, 0, 0 },
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_OKLCH] = {
|
||||
.parent = {
|
||||
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
|
||||
.ref_count = 0,
|
||||
.depth = GDK_MEMORY_FLOAT16,
|
||||
.rendering_color_state = GDK_COLOR_STATE_SRGB,
|
||||
},
|
||||
.name = "oklch",
|
||||
.no_srgb = NULL,
|
||||
.convert_to = {
|
||||
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_oklch_to_srgb,
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_oklch_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_oklch_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_oklch_to_rec2100_linear,
|
||||
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_oklch_to_oklab,
|
||||
},
|
||||
.cicp = { 0, 0, 0, 0 },
|
||||
},
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
/* {{{ Cicp implementation */
|
||||
|
||||
typedef struct _GdkCicpColorState GdkCicpColorState;
|
||||
@@ -509,17 +683,22 @@ struct _GdkCicpColorState
|
||||
|
||||
#define cicp ((GdkCicpColorState *)self)
|
||||
|
||||
TRANSFORM(gdk_cicp_to_srgb, cicp->eotf, cicp->to_srgb, srgb_oetf)
|
||||
TRANSFORM(gdk_cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE)
|
||||
TRANSFORM(gdk_cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, pq_oetf)
|
||||
TRANSFORM(gdk_cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE)
|
||||
TRANSFORM(gdk_cicp_from_srgb, srgb_eotf, cicp->from_srgb, cicp->oetf)
|
||||
TRANSFORM(gdk_cicp_from_srgb_linear, NONE, cicp->from_srgb, cicp->oetf)
|
||||
TRANSFORM(gdk_cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, cicp->oetf)
|
||||
TRANSFORM(gdk_cicp_from_rec2100_linear, NONE, cicp->from_rec2020, cicp->oetf)
|
||||
TRANSFORM(cicp_to_srgb, cicp->eotf, cicp->to_srgb, NONE, IDENTITY, srgb_oetf)
|
||||
TRANSFORM(cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, NONE, IDENTITY, pq_oetf)
|
||||
TRANSFORM(cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE, IDENTITY, NONE)
|
||||
TRANSFORM(cicp_from_srgb, srgb_eotf, cicp->from_srgb, NONE, IDENTITY, cicp->oetf)
|
||||
TRANSFORM(cicp_from_srgb_linear, NONE, cicp->from_srgb, NONE, IDENTITY, cicp->oetf)
|
||||
TRANSFORM(cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, NONE, IDENTITY, cicp->oetf)
|
||||
TRANSFORM(cicp_from_rec2100_linear, NONE, cicp->from_rec2020, NONE, IDENTITY, cicp->oetf)
|
||||
|
||||
#undef cicp
|
||||
|
||||
TRANSFORM_PAIR (cicp_to_oklab, cicp_to_srgb_linear, srgb_linear_to_oklab)
|
||||
TRANSFORM_PAIR (cicp_from_oklab, oklab_to_srgb_linear, cicp_from_srgb_linear)
|
||||
TRANSFORM_PAIR (cicp_to_oklch, cicp_to_srgb_linear, srgb_linear_to_oklch)
|
||||
TRANSFORM_PAIR (cicp_from_oklch, oklch_to_srgb_linear, cicp_from_srgb_linear)
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Vfuncs */
|
||||
|
||||
@@ -572,13 +751,17 @@ gdk_cicp_color_state_get_convert_to (GdkColorState *self,
|
||||
switch (GDK_DEFAULT_COLOR_STATE_ID (target))
|
||||
{
|
||||
case GDK_COLOR_STATE_ID_SRGB:
|
||||
return gdk_cicp_to_srgb;
|
||||
return gdk_convert_cicp_to_srgb;
|
||||
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
|
||||
return gdk_cicp_to_srgb_linear;
|
||||
return gdk_convert_cicp_to_srgb_linear;
|
||||
case GDK_COLOR_STATE_ID_REC2100_PQ:
|
||||
return gdk_cicp_to_rec2100_pq;
|
||||
return gdk_convert_cicp_to_rec2100_pq;
|
||||
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
|
||||
return gdk_cicp_to_rec2100_linear;
|
||||
return gdk_convert_cicp_to_rec2100_linear;
|
||||
case GDK_COLOR_STATE_ID_OKLAB:
|
||||
return gdk_convert_cicp_to_oklab;
|
||||
case GDK_COLOR_STATE_ID_OKLCH:
|
||||
return gdk_convert_cicp_to_oklch;
|
||||
|
||||
case GDK_COLOR_STATE_N_IDS:
|
||||
default:
|
||||
@@ -598,13 +781,17 @@ gdk_cicp_color_state_get_convert_from (GdkColorState *self,
|
||||
switch (GDK_DEFAULT_COLOR_STATE_ID (source))
|
||||
{
|
||||
case GDK_COLOR_STATE_ID_SRGB:
|
||||
return gdk_cicp_from_srgb;
|
||||
return gdk_convert_cicp_from_srgb;
|
||||
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
|
||||
return gdk_cicp_from_srgb_linear;
|
||||
return gdk_convert_cicp_from_srgb_linear;
|
||||
case GDK_COLOR_STATE_ID_REC2100_PQ:
|
||||
return gdk_cicp_from_rec2100_pq;
|
||||
return gdk_convert_cicp_from_rec2100_pq;
|
||||
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
|
||||
return gdk_cicp_from_rec2100_linear;
|
||||
return gdk_convert_cicp_from_rec2100_linear;
|
||||
case GDK_COLOR_STATE_ID_OKLAB:
|
||||
return gdk_convert_cicp_from_oklab;
|
||||
case GDK_COLOR_STATE_ID_OKLCH:
|
||||
return gdk_convert_cicp_from_oklch;
|
||||
|
||||
case GDK_COLOR_STATE_N_IDS:
|
||||
default:
|
||||
|
||||
+7
-1
@@ -49,6 +49,12 @@ GdkColorState * gdk_color_state_get_rec2100_pq (void);
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GdkColorState * gdk_color_state_get_rec2100_linear (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GdkColorState * gdk_color_state_get_oklab (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
GdkColorState * gdk_color_state_get_oklch (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_16
|
||||
gboolean gdk_color_state_equal (GdkColorState *self,
|
||||
GdkColorState *other);
|
||||
@@ -57,6 +63,6 @@ GDK_AVAILABLE_IN_4_16
|
||||
GdkCicpParams *gdk_color_state_create_cicp_params (GdkColorState *self);
|
||||
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorState, gdk_color_state_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorState, gdk_color_state_unref);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -13,6 +13,8 @@ typedef enum
|
||||
GDK_COLOR_STATE_ID_SRGB_LINEAR,
|
||||
GDK_COLOR_STATE_ID_REC2100_PQ,
|
||||
GDK_COLOR_STATE_ID_REC2100_LINEAR,
|
||||
GDK_COLOR_STATE_ID_OKLAB,
|
||||
GDK_COLOR_STATE_ID_OKLCH,
|
||||
|
||||
GDK_COLOR_STATE_N_IDS
|
||||
} GdkColorStateId;
|
||||
@@ -73,12 +75,14 @@ extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
|
||||
#define GDK_COLOR_STATE_SRGB_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
|
||||
#define GDK_COLOR_STATE_REC2100_PQ ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_PQ])
|
||||
#define GDK_COLOR_STATE_REC2100_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_LINEAR])
|
||||
#define GDK_COLOR_STATE_OKLAB ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_OKLAB])
|
||||
#define GDK_COLOR_STATE_OKLCH ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_OKLCH])
|
||||
|
||||
#define GDK_IS_DEFAULT_COLOR_STATE(c) ((GdkDefaultColorState *) (c) >= &gdk_default_color_states[0] && \
|
||||
(GdkDefaultColorState *) (c) < &gdk_default_color_states[GDK_COLOR_STATE_N_IDS])
|
||||
#define GDK_DEFAULT_COLOR_STATE_ID(c) ((GdkColorStateId) (((GdkDefaultColorState *) c) - gdk_default_color_states))
|
||||
|
||||
const char * gdk_color_state_get_name (GdkColorState *color_state);
|
||||
const char * gdk_color_state_get_name (GdkColorState *self);
|
||||
GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState *self);
|
||||
|
||||
GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
|
||||
@@ -124,7 +124,7 @@ gdk_content_provider_new_for_value (const GValue *value)
|
||||
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_VALUE, NULL);
|
||||
g_value_init (&content->value, G_VALUE_TYPE (value));
|
||||
g_value_copy (value, &content->value);
|
||||
|
||||
|
||||
return GDK_CONTENT_PROVIDER (content);
|
||||
}
|
||||
|
||||
@@ -409,7 +409,7 @@ gdk_content_provider_union_init (GdkContentProviderUnion *self)
|
||||
* ```c
|
||||
* gdk_content_provider_new_union ((GdkContentProvider *[2]) {
|
||||
* gdk_content_provider_new_typed (G_TYPE_FILE, file),
|
||||
* gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, texture)
|
||||
* gdk_content_provider_new_typed (G_TYPE_TEXTURE, texture)
|
||||
* }, 2);
|
||||
* ```
|
||||
*
|
||||
@@ -594,7 +594,7 @@ gdk_content_provider_new_for_bytes (const char *mime_type,
|
||||
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_BYTES, NULL);
|
||||
content->mime_type = g_intern_string (mime_type);
|
||||
content->bytes = g_bytes_ref (bytes);
|
||||
|
||||
|
||||
return GDK_CONTENT_PROVIDER (content);
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ struct _GdkDeviceClass
|
||||
};
|
||||
|
||||
void _gdk_device_set_associated_device (GdkDevice *device,
|
||||
GdkDevice *relative);
|
||||
GdkDevice *associated);
|
||||
|
||||
void _gdk_device_reset_axes (GdkDevice *device);
|
||||
guint _gdk_device_add_axis (GdkDevice *device,
|
||||
|
||||
+2
-2
@@ -436,7 +436,7 @@ gdk_display_dispose (GObject *object)
|
||||
g_queue_clear (&display->queued_events);
|
||||
|
||||
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
|
||||
g_clear_pointer (&display->egl_internal_formats, gdk_dmabuf_formats_unref);
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
if (display->vk_dmabuf_formats)
|
||||
{
|
||||
@@ -2002,7 +2002,7 @@ gdk_display_init_dmabuf (GdkDisplay *self)
|
||||
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||
"Initialized support for %zu dmabuf formats",
|
||||
"Initialization finished. Advertising %zu dmabuf formats",
|
||||
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ struct _GdkDisplay
|
||||
|
||||
/* Cached data the EGL dmabuf downloader */
|
||||
GdkDmabufFormats *egl_dmabuf_formats;
|
||||
GdkDmabufFormats *egl_external_formats;
|
||||
GdkDmabufFormats *egl_internal_formats;
|
||||
};
|
||||
|
||||
struct _GdkDisplayClass
|
||||
@@ -154,6 +154,7 @@ struct _GdkDisplayClass
|
||||
void (*beep) (GdkDisplay *display);
|
||||
void (*sync) (GdkDisplay *display);
|
||||
void (*flush) (GdkDisplay *display);
|
||||
gboolean (*has_pending) (GdkDisplay *display);
|
||||
void (*queue_events) (GdkDisplay *display);
|
||||
void (*make_default) (GdkDisplay *display);
|
||||
|
||||
@@ -239,15 +240,15 @@ GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
|
||||
GdkSurface *surface,
|
||||
GError **error);
|
||||
|
||||
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
|
||||
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *self);
|
||||
|
||||
gboolean gdk_display_init_egl (GdkDisplay *display,
|
||||
gboolean gdk_display_init_egl (GdkDisplay *self,
|
||||
int /*EGLenum*/ platform,
|
||||
gpointer native_display,
|
||||
gboolean allow_any,
|
||||
GError **error);
|
||||
gpointer gdk_display_get_egl_display (GdkDisplay *display);
|
||||
gpointer gdk_display_get_egl_config (GdkDisplay *display,
|
||||
gpointer gdk_display_get_egl_display (GdkDisplay *self);
|
||||
gpointer gdk_display_get_egl_config (GdkDisplay *self,
|
||||
GdkMemoryDepth depth);
|
||||
|
||||
void gdk_display_set_rgba (GdkDisplay *display,
|
||||
@@ -288,7 +289,7 @@ void gdk_display_set_double_click_time (GdkDisplay *display,
|
||||
void gdk_display_set_double_click_distance (GdkDisplay *display,
|
||||
guint distance);
|
||||
void gdk_display_set_cursor_theme (GdkDisplay *display,
|
||||
const char *theme,
|
||||
const char *name,
|
||||
int size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+32
-19
@@ -2068,7 +2068,7 @@ gdk_dmabuf_get_mmap_formats (void)
|
||||
continue;
|
||||
|
||||
GDK_DEBUG (DMABUF,
|
||||
"mmap dmabuf format %.4s:%#0" G_GINT64_MODIFIER "x",
|
||||
"mmap advertises dmabuf format %.4s::%016" G_GINT64_MODIFIER "x",
|
||||
(char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
|
||||
|
||||
gdk_dmabuf_formats_builder_add_format (builder,
|
||||
@@ -2082,7 +2082,7 @@ gdk_dmabuf_get_mmap_formats (void)
|
||||
return formats;
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
gdk_dmabuf_do_download_mmap (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
@@ -2093,16 +2093,17 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES];
|
||||
gsize needs_unmap[GDK_DMABUF_MAX_PLANES] = { FALSE, };
|
||||
gsize i, j;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
|
||||
if (dmabuf->modifier != DRM_FORMAT_MOD_LINEAR)
|
||||
return FALSE;
|
||||
|
||||
info = get_drm_format_info (dmabuf->fourcc);
|
||||
|
||||
g_return_if_fail (info && info->download);
|
||||
|
||||
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF,
|
||||
"Using mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
|
||||
gdk_texture_get_width (texture), gdk_texture_get_height (texture),
|
||||
(char *)&dmabuf->fourcc, dmabuf->modifier);
|
||||
if (!info || !info->download)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < dmabuf->n_planes; i++)
|
||||
{
|
||||
@@ -2139,14 +2140,21 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
|
||||
needs_unmap[i] = TRUE;
|
||||
}
|
||||
|
||||
info->download (data,
|
||||
stride,
|
||||
gdk_texture_get_format (texture),
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
dmabuf,
|
||||
src_data,
|
||||
sizes);
|
||||
info->download (data,
|
||||
stride,
|
||||
gdk_texture_get_format (texture),
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
dmabuf,
|
||||
src_data,
|
||||
sizes);
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF,
|
||||
"Used mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
|
||||
gdk_texture_get_width (texture), gdk_texture_get_height (texture),
|
||||
(char *)&dmabuf->fourcc, dmabuf->modifier);
|
||||
|
||||
out:
|
||||
for (i = 0; i < dmabuf->n_planes; i++)
|
||||
@@ -2159,9 +2167,11 @@ out:
|
||||
if (gdk_dmabuf_ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
|
||||
g_warning ("Failed to sync dmabuf: %s", g_strerror (errno));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
gboolean
|
||||
gdk_dmabuf_download_mmap (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorState *color_state,
|
||||
@@ -2170,10 +2180,11 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
|
||||
{
|
||||
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
|
||||
GdkColorState *src_color_state = gdk_texture_get_color_state (texture);
|
||||
gboolean retval;
|
||||
|
||||
if (format == src_format)
|
||||
{
|
||||
gdk_dmabuf_do_download_mmap (texture, data, stride);
|
||||
retval = gdk_dmabuf_do_download_mmap (texture, data, stride);
|
||||
gdk_memory_convert_color_state (data, stride, format,
|
||||
src_color_state, color_state,
|
||||
gdk_texture_get_width (texture),
|
||||
@@ -2191,7 +2202,7 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
|
||||
src_stride = width * gdk_memory_format_bytes_per_pixel (src_format);
|
||||
src_data = g_new (guchar, src_stride * height);
|
||||
|
||||
gdk_dmabuf_do_download_mmap (texture, src_data, src_stride);
|
||||
retval = gdk_dmabuf_do_download_mmap (texture, src_data, src_stride);
|
||||
|
||||
gdk_memory_convert (data, stride, format, color_state,
|
||||
src_data, src_stride, src_format, src_color_state,
|
||||
@@ -2199,6 +2210,8 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
|
||||
|
||||
g_free (src_data);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -19,19 +19,6 @@ gdk_dmabuf_downloader_close (GdkDmabufDownloader *self)
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_dmabuf_downloader_supports (GdkDmabufDownloader *self,
|
||||
GdkDmabufTexture *texture,
|
||||
GError **error)
|
||||
{
|
||||
GdkDmabufDownloaderInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DMABUF_DOWNLOADER (self), FALSE);
|
||||
|
||||
iface = GDK_DMABUF_DOWNLOADER_GET_IFACE (self);
|
||||
return iface->supports (self, texture, error);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_dmabuf_downloader_download (GdkDmabufDownloader *self,
|
||||
GdkDmabufTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
@@ -41,9 +28,8 @@ gdk_dmabuf_downloader_download (GdkDmabufDownloader *self,
|
||||
{
|
||||
GdkDmabufDownloaderInterface *iface;
|
||||
|
||||
g_return_if_fail (GDK_IS_DMABUF_DOWNLOADER (self));
|
||||
g_return_val_if_fail (GDK_IS_DMABUF_DOWNLOADER (self), FALSE);
|
||||
|
||||
iface = GDK_DMABUF_DOWNLOADER_GET_IFACE (self);
|
||||
iface->download (self, texture, format, color_state, data, stride);
|
||||
return iface->download (self, texture, format, color_state, data, stride);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,7 @@ struct _GdkDmabufDownloaderInterface
|
||||
GTypeInterface g_iface;
|
||||
|
||||
void (* close) (GdkDmabufDownloader *downloader);
|
||||
gboolean (* supports) (GdkDmabufDownloader *downloader,
|
||||
GdkDmabufTexture *texture,
|
||||
GError **error);
|
||||
void (* download) (GdkDmabufDownloader *downloader,
|
||||
gboolean (* download) (GdkDmabufDownloader *downloader,
|
||||
GdkDmabufTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorState *color_state,
|
||||
@@ -25,11 +22,8 @@ struct _GdkDmabufDownloaderInterface
|
||||
gsize stride);
|
||||
};
|
||||
|
||||
void gdk_dmabuf_downloader_close (GdkDmabufDownloader *downloader);
|
||||
gboolean gdk_dmabuf_downloader_supports (GdkDmabufDownloader *downloader,
|
||||
GdkDmabufTexture *texture,
|
||||
GError **error);
|
||||
void gdk_dmabuf_downloader_download (GdkDmabufDownloader *downloader,
|
||||
void gdk_dmabuf_downloader_close (GdkDmabufDownloader *self);
|
||||
gboolean gdk_dmabuf_downloader_download (GdkDmabufDownloader *downloader,
|
||||
GdkDmabufTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorState *color_state,
|
||||
|
||||
+28
-25
@@ -40,7 +40,7 @@
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *formats,
|
||||
GdkDmabufFormatsBuilder *external)
|
||||
GdkDmabufFormatsBuilder *internal)
|
||||
{
|
||||
GdkGLContext *context = gdk_display_get_gl_context (display);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
@@ -61,8 +61,8 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
||||
eglQueryDmaBufFormatsEXT (egl_display, num_fourccs, fourccs, &num_fourccs);
|
||||
|
||||
n_mods = 80;
|
||||
modifiers = g_new (guint64, n_mods);
|
||||
external_only = g_new (unsigned int, n_mods);
|
||||
modifiers = g_new0 (guint64, n_mods);
|
||||
external_only = g_new0 (unsigned int, n_mods);
|
||||
|
||||
for (int i = 0; i < num_fourccs; i++)
|
||||
{
|
||||
@@ -94,24 +94,27 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
||||
|
||||
for (int j = 0; j < num_modifiers; j++)
|
||||
{
|
||||
/* All linear formats we support are already added my the mmap downloader.
|
||||
/* All linear formats we support are already advertised by the mmap downloader.
|
||||
* We don't add external formats, unless we can use them (via GLES)
|
||||
*/
|
||||
if (modifiers[j] != DRM_FORMAT_MOD_LINEAR &&
|
||||
(!external_only[j] || gdk_gl_context_get_use_es (context)))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"%s EGL dmabuf format %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
external_only[j] ? "external " : "",
|
||||
(char *) &fourccs[i],
|
||||
modifiers[j]);
|
||||
gboolean advertise = modifiers[j] != DRM_FORMAT_MOD_LINEAR &&
|
||||
(!external_only[j] || gdk_gl_context_get_use_es (context));
|
||||
|
||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"EGL %s %sdmabuf format %.4s::%016" G_GINT64_MODIFIER "x",
|
||||
advertise ? "advertises" : "supports",
|
||||
external_only[j] ? "external " : "",
|
||||
(char *) &fourccs[i],
|
||||
modifiers[j]);
|
||||
|
||||
if (advertise)
|
||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
|
||||
|
||||
if (!external_only[j])
|
||||
{
|
||||
gdk_dmabuf_formats_builder_add_format (internal, fourccs[i], modifiers[j]);
|
||||
all_external = FALSE;
|
||||
}
|
||||
if (external_only[j])
|
||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
|
||||
else
|
||||
all_external = FALSE;
|
||||
}
|
||||
|
||||
/* Accept implicit modifiers as long as we accept the format at all.
|
||||
@@ -123,8 +126,8 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
|
||||
*/
|
||||
if (!all_external || gdk_gl_context_get_use_es (context))
|
||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||
if (all_external)
|
||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||
if (!all_external)
|
||||
gdk_dmabuf_formats_builder_add_format (internal, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||
}
|
||||
|
||||
g_free (modifiers);
|
||||
@@ -213,7 +216,6 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating EGLImage for dmabuf failed: %#x",
|
||||
eglGetError ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return image;
|
||||
@@ -229,6 +231,7 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
|
||||
typedef struct _GskRenderer GskRenderer;
|
||||
|
||||
extern GskRenderer * gsk_gl_renderer_new (void);
|
||||
extern GskRenderer * gsk_ngl_renderer_new (void);
|
||||
extern gboolean gsk_renderer_realize_for_display (GskRenderer *renderer,
|
||||
GdkDisplay *display,
|
||||
GError **error);
|
||||
@@ -238,7 +241,7 @@ gdk_dmabuf_egl_init (GdkDisplay *display)
|
||||
{
|
||||
#if defined (HAVE_DMABUF) && defined (HAVE_EGL)
|
||||
GdkDmabufFormatsBuilder *formats;
|
||||
GdkDmabufFormatsBuilder *external;
|
||||
GdkDmabufFormatsBuilder *internal;
|
||||
gboolean retval = FALSE;
|
||||
GError *error = NULL;
|
||||
GskRenderer *renderer;
|
||||
@@ -254,16 +257,16 @@ gdk_dmabuf_egl_init (GdkDisplay *display)
|
||||
}
|
||||
|
||||
formats = gdk_dmabuf_formats_builder_new ();
|
||||
external = gdk_dmabuf_formats_builder_new ();
|
||||
internal = gdk_dmabuf_formats_builder_new ();
|
||||
|
||||
previous = gdk_gl_context_get_current ();
|
||||
if (previous)
|
||||
g_object_ref (previous);
|
||||
|
||||
retval = gdk_dmabuf_egl_downloader_collect_formats (display, formats, external);
|
||||
retval = gdk_dmabuf_egl_downloader_collect_formats (display, formats, internal);
|
||||
|
||||
display->egl_dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (formats);
|
||||
display->egl_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
|
||||
display->egl_internal_formats = gdk_dmabuf_formats_builder_free_to_formats (internal);
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
@@ -272,7 +275,7 @@ gdk_dmabuf_egl_init (GdkDisplay *display)
|
||||
return;
|
||||
}
|
||||
|
||||
renderer = gsk_gl_renderer_new ();
|
||||
renderer = gsk_ngl_renderer_new ();
|
||||
|
||||
if (!gsk_renderer_realize_for_display (renderer, display, &error))
|
||||
{
|
||||
|
||||
@@ -55,6 +55,6 @@ GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
||||
const GdkDmabufFormats *formats2);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkDmabufFormats, gdk_dmabuf_formats_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkDmabufFormats, gdk_dmabuf_formats_unref);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -27,7 +27,7 @@ void gdk_dmabuf_close_fds (GdkDmabuf
|
||||
#ifdef HAVE_DMABUF
|
||||
|
||||
GdkDmabufFormats * gdk_dmabuf_get_mmap_formats (void) G_GNUC_CONST;
|
||||
void gdk_dmabuf_download_mmap (GdkTexture *texture,
|
||||
gboolean gdk_dmabuf_download_mmap (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorState *color_state,
|
||||
guchar *data,
|
||||
|
||||
+49
-41
@@ -50,7 +50,6 @@ struct _GdkDmabufTexture
|
||||
GdkTexture parent_instance;
|
||||
|
||||
GdkDisplay *display;
|
||||
GdkDmabufDownloader *downloader;
|
||||
|
||||
GdkDmabuf dmabuf;
|
||||
|
||||
@@ -85,7 +84,6 @@ gdk_dmabuf_texture_dispose (GObject *object)
|
||||
self->destroy = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&self->downloader);
|
||||
g_clear_object (&self->display);
|
||||
|
||||
G_OBJECT_CLASS (gdk_dmabuf_texture_parent_class)->dispose (object);
|
||||
@@ -107,16 +105,49 @@ static gboolean
|
||||
gdk_dmabuf_texture_invoke_callback (gpointer data)
|
||||
{
|
||||
Download *download = data;
|
||||
GdkDisplay *display = download->texture->display;
|
||||
|
||||
gdk_dmabuf_downloader_download (download->texture->downloader,
|
||||
download->texture,
|
||||
download->format,
|
||||
download->color_state,
|
||||
download->data,
|
||||
download->stride);
|
||||
if (display->egl_downloader &&
|
||||
gdk_dmabuf_downloader_download (display->egl_downloader,
|
||||
download->texture,
|
||||
download->format,
|
||||
download->color_state,
|
||||
download->data,
|
||||
download->stride))
|
||||
{
|
||||
/* Successfully downloaded using EGL */
|
||||
}
|
||||
else if (display->vk_downloader &&
|
||||
gdk_dmabuf_downloader_download (display->vk_downloader,
|
||||
download->texture,
|
||||
download->format,
|
||||
download->color_state,
|
||||
download->data,
|
||||
download->stride))
|
||||
{
|
||||
/* Successfully downloaded using Vulkan */
|
||||
}
|
||||
#ifdef HAVE_DMABUF
|
||||
else if (gdk_dmabuf_download_mmap (GDK_TEXTURE (download->texture),
|
||||
download->format,
|
||||
download->color_state,
|
||||
download->data,
|
||||
download->stride))
|
||||
{
|
||||
/* Successfully downloaded using mmap */
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
const GdkDmabuf *dmabuf = gdk_dmabuf_texture_get_dmabuf (download->texture);
|
||||
|
||||
g_critical ("Failed to download %dx%d dmabuf texture (format %.4s:%#" G_GINT64_MODIFIER "x)",
|
||||
gdk_texture_get_width (GDK_TEXTURE (download->texture)),
|
||||
gdk_texture_get_height (GDK_TEXTURE (download->texture)),
|
||||
(char *)&(dmabuf->fourcc), dmabuf->modifier);
|
||||
}
|
||||
|
||||
g_atomic_int_set (&download->spinlock, 1);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -130,14 +161,6 @@ gdk_dmabuf_texture_download (GdkTexture *texture,
|
||||
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
|
||||
Download download = { self, format, color_state, data, stride, 0 };
|
||||
|
||||
if (self->downloader == NULL)
|
||||
{
|
||||
#ifdef HAVE_DMABUF
|
||||
gdk_dmabuf_download_mmap (texture, format, color_state, data, stride);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
g_main_context_invoke (NULL, gdk_dmabuf_texture_invoke_callback, &download);
|
||||
|
||||
while (g_atomic_int_get (&download.spinlock) == 0);
|
||||
@@ -232,37 +255,22 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
: GDK_MEMORY_R8G8B8A8;
|
||||
}
|
||||
|
||||
if (display->egl_downloader)
|
||||
if (!gdk_dmabuf_formats_contains (display->dmabuf_formats, dmabuf.fourcc, dmabuf.modifier))
|
||||
{
|
||||
if (gdk_dmabuf_downloader_supports (display->egl_downloader, self, error))
|
||||
self->downloader = g_object_ref (display->egl_downloader);
|
||||
}
|
||||
|
||||
if (!self->downloader && display->vk_downloader)
|
||||
{
|
||||
g_clear_error (error);
|
||||
if (gdk_dmabuf_downloader_supports (display->vk_downloader, self, error))
|
||||
self->downloader = g_object_ref (display->vk_downloader);
|
||||
}
|
||||
|
||||
if (!self->downloader)
|
||||
{
|
||||
if (!gdk_dmabuf_formats_contains (gdk_dmabuf_get_mmap_formats (), dmabuf.fourcc, dmabuf.modifier))
|
||||
{
|
||||
g_object_unref (self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_clear_error (error);
|
||||
g_set_error (error,
|
||||
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
|
||||
"Unsupported dmabuf format: %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
(char *) &dmabuf.fourcc, dmabuf.modifier);
|
||||
g_object_unref (self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u, downloader %s",
|
||||
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u",
|
||||
(char *) &dmabuf.fourcc, dmabuf.modifier,
|
||||
gdk_dmabuf_texture_builder_get_premultiplied (builder) ? " premultiplied, " : "",
|
||||
dmabuf.n_planes,
|
||||
GDK_TEXTURE (self)->format,
|
||||
self->downloader ? G_OBJECT_TYPE_NAME (self->downloader) : "none");
|
||||
GDK_TEXTURE (self)->format);
|
||||
|
||||
/* Set this only once we know that the texture will be created.
|
||||
* Otherwise dispose() will run the callback */
|
||||
|
||||
@@ -375,7 +375,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:update-region:
|
||||
*
|
||||
* The update region for [property@Gdk.DmabufTextureBuilder:update-texture].
|
||||
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
@@ -496,7 +496,7 @@ gdk_dmabuf_texture_builder_get_width (GdkDmabufTextureBuilder *self)
|
||||
*
|
||||
* Sets the width of the texture.
|
||||
*
|
||||
* The width must be set before calling [method@Gdk.DmabufTextureBuilder.build].
|
||||
* The width must be set before calling [method@Gdk.GLTextureBuilder.build].
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
@@ -540,7 +540,7 @@ gdk_dmabuf_texture_builder_get_height (GdkDmabufTextureBuilder *self)
|
||||
*
|
||||
* Sets the height of the texture.
|
||||
*
|
||||
* The height must be set before calling [method@Gdk.DmabufTextureBuilder.build].
|
||||
* The height must be set before calling [method@Gdk.GLTextureBuilder.build].
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
@@ -588,7 +588,7 @@ gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self)
|
||||
*
|
||||
* The format is specified as a fourcc code.
|
||||
*
|
||||
* The format must be set before calling [method@Gdk.DmabufTextureBuilder.build].
|
||||
* The format must be set before calling [method@Gdk.GLTextureBuilder.build].
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
@@ -807,7 +807,7 @@ gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
|
||||
*
|
||||
* Sets the stride for a plane.
|
||||
*
|
||||
* The stride must be set for all planes before calling [method@Gdk.DmabufTextureBuilder.build].
|
||||
* The stride must be set for all planes before calling [method@Gdk.GLTextureBuilder.build].
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *builder);
|
||||
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *self);
|
||||
|
||||
void gdk_dmabuf_texture_builder_set_dmabuf (GdkDmabufTextureBuilder *builder,
|
||||
void gdk_dmabuf_texture_builder_set_dmabuf (GdkDmabufTextureBuilder *self,
|
||||
const GdkDmabuf *dmabuf);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -511,9 +511,9 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
|
||||
* Use `GskRenderNode` and `GskRenderer`.
|
||||
*/
|
||||
const cairo_region_t *
|
||||
_gdk_draw_context_get_frame_region (GdkDrawContext *context)
|
||||
_gdk_draw_context_get_frame_region (GdkDrawContext *self)
|
||||
{
|
||||
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
||||
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (self);
|
||||
|
||||
return priv->frame_region;
|
||||
}
|
||||
|
||||
+6
-6
@@ -87,12 +87,12 @@ typedef enum
|
||||
/**
|
||||
* GdkModifierType:
|
||||
* @GDK_SHIFT_MASK: the Shift key.
|
||||
* @GDK_LOCK_MASK: a Lock key (depending on the Windowing System configuration,
|
||||
* this may either be <kbd>CapsLock</kbd> or <kbd>ShiftLock</kbd>).
|
||||
* @GDK_LOCK_MASK: a Lock key (depending on the modifier mapping of the
|
||||
* X server this may either be CapsLock or ShiftLock).
|
||||
* @GDK_CONTROL_MASK: the Control key.
|
||||
* @GDK_ALT_MASK: the fourth modifier key (it depends on the Windowing System
|
||||
* configuration which key is interpreted as this modifier, but normally it
|
||||
* is the <kbd>Alt</kbd> key).
|
||||
* @GDK_ALT_MASK: the fourth modifier key (it depends on the modifier
|
||||
* mapping of the X server which key is interpreted as this modifier, but
|
||||
* normally it is the Alt key).
|
||||
* @GDK_BUTTON1_MASK: the first mouse button.
|
||||
* @GDK_BUTTON2_MASK: the second mouse button.
|
||||
* @GDK_BUTTON3_MASK: the third mouse button.
|
||||
@@ -109,7 +109,7 @@ typedef enum
|
||||
* Apple, CapsLock or ShiftLock.
|
||||
*
|
||||
* Note that GDK may add internal values to events which include values outside
|
||||
* of this enumeration. Your code should preserve and ignore them. You can use
|
||||
* of this enumeration. Your code should preserve and ignore them. You can use
|
||||
* %GDK_MODIFIER_MASK to remove all private values.
|
||||
*/
|
||||
typedef enum
|
||||
|
||||
-11
@@ -82,7 +82,6 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
cairo_surface_t *image;
|
||||
guint framebuffer;
|
||||
int alpha_size = 0;
|
||||
int major, minor, version;
|
||||
gboolean es_use_bgra = FALSE;
|
||||
|
||||
paint_context = gdk_surface_get_paint_gl_context (surface, NULL);
|
||||
@@ -118,16 +117,6 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_gl_context_get_version (paint_context, &major, &minor);
|
||||
version = major * 100 + minor;
|
||||
|
||||
/* TODO: Use glTexSubImage2D() and do a row-by-row copy to replace
|
||||
* the GL_UNPACK_ROW_LENGTH support
|
||||
*/
|
||||
if (gdk_gl_context_get_use_es (paint_context) &&
|
||||
!(version >= 300 || gdk_gl_context_has_feature (paint_context, GDK_GL_FEATURE_UNPACK_SUBIMAGE)))
|
||||
return;
|
||||
|
||||
/* TODO: avoid reading back non-required data due to dest clip */
|
||||
image = cairo_surface_create_similar_image (cairo_get_target (cr),
|
||||
(alpha_size == 0) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32,
|
||||
|
||||
+355
-153
@@ -105,9 +105,6 @@
|
||||
|
||||
static const GdkDebugKey gdk_gl_feature_keys[] = {
|
||||
{ "debug", GDK_GL_FEATURE_DEBUG, "GL_KHR_debug" },
|
||||
{ "unpack-subimage", GDK_GL_FEATURE_UNPACK_SUBIMAGE, "GL_EXT_unpack_subimage" },
|
||||
{ "half-float", GDK_GL_FEATURE_VERTEX_HALF_FLOAT, "GL_OES_vertex_half_float" },
|
||||
{ "sync", GDK_GL_FEATURE_SYNC, "GL_ARB_sync" },
|
||||
{ "base-instance", GDK_GL_FEATURE_BASE_INSTANCE, "GL_ARB_base_instance" },
|
||||
{ "buffer-storage", GDK_GL_FEATURE_BUFFER_STORAGE, "GL_EXT_buffer_storage" },
|
||||
};
|
||||
@@ -385,6 +382,8 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
return 0;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
|
||||
|
||||
priv->egl_context = ctx;
|
||||
gdk_gl_context_set_version (context, &supported_versions[j]);
|
||||
gdk_gl_context_set_is_legacy (context, legacy);
|
||||
@@ -1058,16 +1057,9 @@ gdk_gl_context_get_matching_version (GdkGLContext *context,
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
if (api == GDK_GL_API_GL)
|
||||
{
|
||||
if (legacy)
|
||||
min_version = GDK_GL_MIN_GL_LEGACY_VERSION;
|
||||
else
|
||||
min_version = GDK_GL_MIN_GL_VERSION;
|
||||
}
|
||||
min_version = GDK_GL_MIN_GL_VERSION;
|
||||
else
|
||||
{
|
||||
min_version = GDK_GL_MIN_GLES_VERSION;
|
||||
}
|
||||
min_version = GDK_GL_MIN_GLES_VERSION;
|
||||
|
||||
if (gdk_gl_version_greater_equal (&priv->required, &min_version))
|
||||
*out_version = priv->required;
|
||||
@@ -1590,38 +1582,35 @@ gdk_gl_context_init_memory_flags (GdkGLContext *self)
|
||||
priv->memory_flags[GDK_MEMORY_G8A8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
#endif
|
||||
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
/* GLES 3.0.6 spec, table 3.13 */
|
||||
priv->memory_flags[GDK_MEMORY_G8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
|
||||
/* no changes in GLES 3.1 spec, table 8.13 */
|
||||
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
|
||||
{
|
||||
/* GLES 3.0.6 spec, table 3.13 */
|
||||
priv->memory_flags[GDK_MEMORY_G8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
|
||||
/* no changes in GLES 3.1 spec, table 8.13 */
|
||||
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
|
||||
{
|
||||
/* GLES 3.2 spec, table 8.10 */
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
}
|
||||
/* GLES 3.2 spec, table 8.10 */
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
|
||||
}
|
||||
|
||||
if (epoxy_has_gl_extension ("GL_OES_rgb8_rgba8"))
|
||||
@@ -1629,64 +1618,55 @@ gdk_gl_context_init_memory_flags (GdkGLContext *self)
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_EXT_abgr"))
|
||||
{
|
||||
priv->memory_flags[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
priv->memory_flags[GDK_MEMORY_X8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_X8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888"))
|
||||
{
|
||||
priv->memory_flags[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_B8G8R8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
priv->memory_flags[GDK_MEMORY_B8G8R8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_B8G8R8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
|
||||
/* Technically, those extensions are supported on GLES2.
|
||||
* However, GTK uses the wrong format/type pairs with them, so we don't enable them.
|
||||
*/
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
if (epoxy_has_gl_extension ("GL_EXT_texture_norm16"))
|
||||
{
|
||||
if (epoxy_has_gl_extension ("GL_EXT_texture_norm16"))
|
||||
{
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_half_float"))
|
||||
{
|
||||
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
|
||||
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_half_float"))
|
||||
flags |= GDK_GL_FORMAT_RENDERABLE;
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_half_float_linear"))
|
||||
flags |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= flags;
|
||||
/* disabled for now, see https://gitlab.freedesktop.org/mesa/mesa/-/issues/10378 */
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= flags;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_float"))
|
||||
{
|
||||
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
|
||||
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_float"))
|
||||
flags |= GDK_GL_FORMAT_RENDERABLE;
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_float_linear"))
|
||||
flags |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= flags;
|
||||
}
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_half_float"))
|
||||
{
|
||||
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
|
||||
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_half_float"))
|
||||
flags |= GDK_GL_FORMAT_RENDERABLE;
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_half_float_linear"))
|
||||
flags |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= flags;
|
||||
/* disabled for now, see https://gitlab.freedesktop.org/mesa/mesa/-/issues/10378 */
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= flags;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_float"))
|
||||
{
|
||||
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
|
||||
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_float"))
|
||||
flags |= GDK_GL_FORMAT_RENDERABLE;
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_float_linear"))
|
||||
flags |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= flags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1701,32 +1681,11 @@ gdk_gl_version_init_epoxy (GdkGLVersion *version)
|
||||
static GdkGLFeatures
|
||||
gdk_gl_context_check_features (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLFeatures features = 0;
|
||||
|
||||
if (gdk_gl_context_get_use_es (context))
|
||||
{
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)) ||
|
||||
epoxy_has_gl_extension ("GL_EXT_unpack_subimage"))
|
||||
features |= GDK_GL_FEATURE_UNPACK_SUBIMAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
features |= GDK_GL_FEATURE_UNPACK_SUBIMAGE;
|
||||
}
|
||||
|
||||
if (epoxy_has_gl_extension ("GL_KHR_debug"))
|
||||
features |= GDK_GL_FEATURE_DEBUG;
|
||||
|
||||
if (gdk_gl_context_check_version (context, "3.0", "3.0") ||
|
||||
epoxy_has_gl_extension ("GL_OES_vertex_half_float"))
|
||||
features |= GDK_GL_FEATURE_VERTEX_HALF_FLOAT;
|
||||
|
||||
if (gdk_gl_context_check_version (context, "3.2", "3.0") ||
|
||||
epoxy_has_gl_extension ("GL_ARB_sync") ||
|
||||
epoxy_has_gl_extension ("GL_APPLE_sync"))
|
||||
features |= GDK_GL_FEATURE_SYNC;
|
||||
|
||||
if (gdk_gl_context_check_version (context, "4.2", "9.9") ||
|
||||
epoxy_has_gl_extension ("GL_EXT_base_instance") ||
|
||||
epoxy_has_gl_extension ("GL_ARB_base_instance"))
|
||||
@@ -1793,20 +1752,22 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
{
|
||||
int i, max_texture_size;
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
gdk_debug_message ("%s version: %d.%d (%s)",
|
||||
gdk_debug_message ("%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Max texture size: %d\n",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
|
||||
priv->is_legacy ? "legacy" : "core");
|
||||
gdk_debug_message ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
gdk_debug_message ("Max texture size: %d", max_texture_size);
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
max_texture_size);
|
||||
gdk_debug_message ("Enabled features (use GDK_GL_DISABLE env var to disable):");
|
||||
for (i = 0; i < G_N_ELEMENTS (gdk_gl_feature_keys); i++)
|
||||
{
|
||||
gdk_debug_message (" %s: %s",
|
||||
gdk_gl_feature_keys[i].key,
|
||||
(priv->features & gdk_gl_feature_keys[i].value) ? "✓" :
|
||||
(priv->features & gdk_gl_feature_keys[i].value) ? "YES" :
|
||||
((disabled_features & gdk_gl_feature_keys[i].value) ? "disabled via env var" :
|
||||
(((supported_features & gdk_gl_feature_keys[i].value) == 0) ? "✗" :
|
||||
(((supported_features & gdk_gl_feature_keys[i].value) == 0) ? "not supported" :
|
||||
"Hum, what? This should not happen.")));
|
||||
}
|
||||
}
|
||||
@@ -2258,59 +2219,26 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
|
||||
gdk_dmabuf_egl_init (display);
|
||||
|
||||
if (gdk_dmabuf_formats_contains (display->egl_dmabuf_formats, dmabuf->fourcc, dmabuf->modifier))
|
||||
if (gdk_dmabuf_formats_contains (display->egl_internal_formats, dmabuf->fourcc, dmabuf->modifier))
|
||||
{
|
||||
/* This is the path for modern drivers that support modifiers */
|
||||
|
||||
if (!gdk_dmabuf_formats_contains (display->egl_external_formats, dmabuf->fourcc, dmabuf->modifier))
|
||||
{
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
GL_TEXTURE_2D);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Import of %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_2D texture",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
*external = FALSE;
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
if (!gdk_gl_context_get_use_es (self))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't import external_only %.4s:%#" G_GINT64_MODIFIER "x outside of GLES",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
GL_TEXTURE_EXTERNAL_OES);
|
||||
GL_TEXTURE_2D);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Import of external_only %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
|
||||
"Import of %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_EXTERNAL_OES texture",
|
||||
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_2D texture",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
*external = TRUE;
|
||||
*external = FALSE;
|
||||
return texture_id;
|
||||
}
|
||||
else
|
||||
@@ -2467,3 +2395,277 @@ out:
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_find_format (GdkGLContext *self,
|
||||
GdkMemoryAlpha alpha,
|
||||
GLint gl_format,
|
||||
GLint gl_type,
|
||||
GdkMemoryFormat *out_format)
|
||||
{
|
||||
GdkMemoryFormat format;
|
||||
|
||||
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
|
||||
{
|
||||
GLint q_internal_format, q_internal_srgb_format;
|
||||
GLenum q_format, q_type;
|
||||
GLint q_swizzle[4];
|
||||
|
||||
if (gdk_memory_format_alpha (format) != alpha)
|
||||
continue;
|
||||
|
||||
if (!(gdk_gl_context_get_format_flags (self, format) & GDK_GL_FORMAT_RENDERABLE))
|
||||
continue;
|
||||
|
||||
gdk_memory_format_gl_format (format,
|
||||
gdk_gl_context_get_use_es (self),
|
||||
&q_internal_format,
|
||||
&q_internal_srgb_format,
|
||||
&q_format,
|
||||
&q_type,
|
||||
q_swizzle);
|
||||
|
||||
if (q_format != gl_format || q_type != gl_type)
|
||||
continue;
|
||||
|
||||
*out_format = format;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_context_download (GdkGLContext *self,
|
||||
GLuint tex_id,
|
||||
GdkMemoryFormat tex_format,
|
||||
GdkColorState *tex_color_state,
|
||||
guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
GdkColorState *dest_color_state,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
gsize expected_stride;
|
||||
GLint gl_internal_format, gl_internal_srgb_format;
|
||||
GLenum gl_format, gl_type;
|
||||
GLint gl_swizzle[4];
|
||||
|
||||
expected_stride = width * gdk_memory_format_bytes_per_pixel (dest_format);
|
||||
|
||||
if (!gdk_gl_context_get_use_es (self) &&
|
||||
((gdk_gl_context_get_format_flags (self, tex_format) & GDK_GL_FORMAT_USABLE) == GDK_GL_FORMAT_USABLE))
|
||||
{
|
||||
gdk_memory_format_gl_format (tex_format,
|
||||
gdk_gl_context_get_use_es (self),
|
||||
&gl_internal_format, &gl_internal_srgb_format,
|
||||
&gl_format, &gl_type, gl_swizzle);
|
||||
if (dest_stride == expected_stride &&
|
||||
dest_format == tex_format)
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_format,
|
||||
gl_type,
|
||||
dest_data);
|
||||
|
||||
gdk_memory_convert_color_state (dest_data,
|
||||
dest_stride,
|
||||
dest_format,
|
||||
dest_color_state,
|
||||
tex_color_state,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsize stride = width * gdk_memory_format_bytes_per_pixel (tex_format);
|
||||
guchar *pixels = g_malloc_n (stride, height);
|
||||
|
||||
glPixelStorei (GL_PACK_ALIGNMENT, 1);
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_format,
|
||||
gl_type,
|
||||
pixels);
|
||||
|
||||
gdk_memory_convert (dest_data,
|
||||
dest_stride,
|
||||
dest_format,
|
||||
dest_color_state,
|
||||
pixels,
|
||||
stride,
|
||||
tex_format,
|
||||
tex_color_state,
|
||||
width,
|
||||
height);
|
||||
|
||||
g_free (pixels);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkMemoryFormat actual_format;
|
||||
GLenum gl_read_format, gl_read_type;
|
||||
GLuint fbo;
|
||||
|
||||
glGenFramebuffers (1, &fbo);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0);
|
||||
if (gdk_gl_context_check_version (self, "4.3", "3.1"))
|
||||
{
|
||||
GLint read_format, read_type;
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
|
||||
if (gdk_gl_context_find_format (self, gdk_memory_format_alpha (tex_format), read_format, read_type, &actual_format))
|
||||
{
|
||||
gl_read_format = read_format;
|
||||
gl_read_type = read_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (tex_format, FALSE));
|
||||
if (gdk_memory_format_alpha (tex_format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
gdk_gl_context_get_use_es (self),
|
||||
&gl_internal_format, &gl_internal_srgb_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (tex_format, FALSE));
|
||||
if (gdk_memory_format_alpha (tex_format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
gdk_gl_context_get_use_es (self),
|
||||
&gl_internal_format, &gl_internal_srgb_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
|
||||
if (dest_format == actual_format &&
|
||||
(dest_stride == expected_stride))
|
||||
{
|
||||
glReadPixels (0, 0,
|
||||
width, height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
dest_data);
|
||||
|
||||
gdk_memory_convert_color_state (dest_data,
|
||||
dest_stride,
|
||||
dest_format,
|
||||
dest_color_state,
|
||||
tex_color_state,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsize actual_bpp = gdk_memory_format_bytes_per_pixel (actual_format);
|
||||
gsize stride = actual_bpp * width;
|
||||
guchar *pixels = g_malloc_n (stride, height);
|
||||
|
||||
glPixelStorei (GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels (0, 0,
|
||||
width, height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
pixels);
|
||||
|
||||
/* Fix up gles inadequacies */
|
||||
|
||||
if (gl_read_format == GL_RGBA &&
|
||||
gl_read_type == GL_UNSIGNED_BYTE &&
|
||||
(tex_format == GDK_MEMORY_G8A8 ||
|
||||
tex_format == GDK_MEMORY_G8A8_PREMULTIPLIED ||
|
||||
tex_format == GDK_MEMORY_G8 ||
|
||||
tex_format == GDK_MEMORY_A8))
|
||||
{
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
guchar *data = &pixels[y * stride + x * actual_bpp];
|
||||
if (tex_format == GDK_MEMORY_G8A8 ||
|
||||
tex_format == GDK_MEMORY_G8A8_PREMULTIPLIED)
|
||||
{
|
||||
data[3] = data[1];
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
}
|
||||
else if (tex_format == GDK_MEMORY_G8)
|
||||
{
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
data[3] = 0xff;
|
||||
}
|
||||
else if (tex_format == GDK_MEMORY_A8)
|
||||
{
|
||||
data[3] = data[0];
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_read_format == GL_RGBA &&
|
||||
gl_read_type == GL_UNSIGNED_SHORT &&
|
||||
(tex_format == GDK_MEMORY_G16A16 ||
|
||||
tex_format == GDK_MEMORY_G16A16_PREMULTIPLIED ||
|
||||
tex_format == GDK_MEMORY_G16 ||
|
||||
tex_format == GDK_MEMORY_A16))
|
||||
{
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
guint16 *data = (guint16 *) &pixels[y * stride + x * actual_bpp];
|
||||
if (tex_format == GDK_MEMORY_G16A16 ||
|
||||
tex_format == GDK_MEMORY_G16A16_PREMULTIPLIED)
|
||||
{
|
||||
data[3] = data[1];
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
}
|
||||
else if (tex_format == GDK_MEMORY_G16)
|
||||
{
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
data[3] = 0xffff;
|
||||
}
|
||||
else if (tex_format == GDK_MEMORY_A16)
|
||||
{
|
||||
data[3] = data[0];
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gdk_memory_convert (dest_data,
|
||||
dest_stride,
|
||||
dest_format,
|
||||
dest_color_state,
|
||||
pixels,
|
||||
stride,
|
||||
actual_format,
|
||||
tex_color_state,
|
||||
width,
|
||||
height);
|
||||
|
||||
g_free (pixels);
|
||||
}
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers (1, &fbo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,8 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GDK_GL_FEATURE_DEBUG = 1 << 0,
|
||||
GDK_GL_FEATURE_UNPACK_SUBIMAGE = 1 << 1,
|
||||
GDK_GL_FEATURE_VERTEX_HALF_FLOAT = 1 << 2,
|
||||
GDK_GL_FEATURE_SYNC = 1 << 3,
|
||||
GDK_GL_FEATURE_BASE_INSTANCE = 1 << 4,
|
||||
GDK_GL_FEATURE_BUFFER_STORAGE = 1 << 5,
|
||||
GDK_GL_FEATURE_BASE_INSTANCE = 1 << 1,
|
||||
GDK_GL_FEATURE_BUFFER_STORAGE = 1 << 2,
|
||||
} GdkGLFeatures;
|
||||
|
||||
typedef enum {
|
||||
@@ -133,16 +130,16 @@ void gdk_gl_context_set_version (GdkGLContext
|
||||
const GdkGLVersion *version);
|
||||
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
gboolean is_legacy);
|
||||
gboolean gdk_gl_context_check_gl_version (GdkGLContext *context,
|
||||
gboolean gdk_gl_context_check_gl_version (GdkGLContext *self,
|
||||
const GdkGLVersion *gl_version,
|
||||
const GdkGLVersion *gles_version);
|
||||
|
||||
static inline gboolean
|
||||
gdk_gl_context_check_version (GdkGLContext *context,
|
||||
gdk_gl_context_check_version (GdkGLContext *self,
|
||||
const char *gl_version,
|
||||
const char *gles_version)
|
||||
{
|
||||
return gdk_gl_context_check_gl_version (context,
|
||||
return gdk_gl_context_check_gl_version (self,
|
||||
gl_version ? &GDK_GL_VERSION_STRING (gl_version) : NULL,
|
||||
gles_version ? &GDK_GL_VERSION_STRING (gles_version) : NULL);
|
||||
}
|
||||
@@ -181,6 +178,17 @@ gboolean gdk_gl_context_has_vertex_arrays (GdkGLContext
|
||||
|
||||
double gdk_gl_context_get_scale (GdkGLContext *self);
|
||||
|
||||
void gdk_gl_context_download (GdkGLContext *self,
|
||||
GLuint tex_id,
|
||||
GdkMemoryFormat tex_format,
|
||||
GdkColorState *tex_color_state,
|
||||
guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
GdkColorState *dest_color_state,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
guint gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
|
||||
+13
-264
@@ -151,276 +151,26 @@ struct _Download
|
||||
gsize stride;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gdk_gl_texture_find_format (GdkGLContext *context,
|
||||
GdkMemoryAlpha alpha,
|
||||
GLint gl_format,
|
||||
GLint gl_type,
|
||||
GdkMemoryFormat *out_format)
|
||||
{
|
||||
GdkMemoryFormat format;
|
||||
|
||||
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
|
||||
{
|
||||
GLint q_internal_format, q_internal_srgb_format;
|
||||
GLenum q_format, q_type;
|
||||
GLint q_swizzle[4];
|
||||
|
||||
if (gdk_memory_format_alpha (format) != alpha)
|
||||
continue;
|
||||
|
||||
if (!(gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_RENDERABLE))
|
||||
continue;
|
||||
|
||||
gdk_memory_format_gl_format (format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&q_internal_format,
|
||||
&q_internal_srgb_format,
|
||||
&q_format,
|
||||
&q_type,
|
||||
q_swizzle);
|
||||
|
||||
if (q_format != gl_format || q_type != gl_type)
|
||||
continue;
|
||||
|
||||
*out_format = format;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
static void
|
||||
gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
GdkGLContext *context,
|
||||
gpointer download_)
|
||||
{
|
||||
GdkTexture *texture = GDK_TEXTURE (self);
|
||||
GdkMemoryFormat format;
|
||||
gsize expected_stride;
|
||||
Download *download = download_;
|
||||
GLint gl_internal_format, gl_internal_srgb_format;
|
||||
GLenum gl_format, gl_type;
|
||||
GLint gl_swizzle[4];
|
||||
|
||||
format = gdk_texture_get_format (texture),
|
||||
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
|
||||
|
||||
if (!gdk_gl_context_get_use_es (context) &&
|
||||
((gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_USABLE) == GDK_GL_FORMAT_USABLE))
|
||||
{
|
||||
gdk_memory_format_gl_format (format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&gl_internal_format, &gl_internal_srgb_format,
|
||||
&gl_format, &gl_type, gl_swizzle);
|
||||
if (download->stride == expected_stride &&
|
||||
download->format == format)
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_format,
|
||||
gl_type,
|
||||
download->data);
|
||||
|
||||
gdk_memory_convert_color_state (download->data,
|
||||
download->stride,
|
||||
download->format,
|
||||
download->color_state,
|
||||
texture->color_state,
|
||||
texture->width,
|
||||
texture->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsize stride = texture->width * gdk_memory_format_bytes_per_pixel (format);
|
||||
guchar *pixels = g_malloc_n (stride, texture->height);
|
||||
|
||||
glPixelStorei (GL_PACK_ALIGNMENT, 1);
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
gl_format,
|
||||
gl_type,
|
||||
pixels);
|
||||
|
||||
gdk_memory_convert (download->data,
|
||||
download->stride,
|
||||
download->format,
|
||||
download->color_state,
|
||||
pixels,
|
||||
stride,
|
||||
format,
|
||||
texture->color_state,
|
||||
texture->width,
|
||||
texture->height);
|
||||
|
||||
g_free (pixels);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkMemoryFormat actual_format;
|
||||
GLenum gl_read_format, gl_read_type;
|
||||
GLuint fbo;
|
||||
|
||||
glGenFramebuffers (1, &fbo);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
|
||||
{
|
||||
GLint read_format, read_type;
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
|
||||
if (gdk_gl_texture_find_format (context, gdk_memory_format_alpha (format), read_format, read_type, &actual_format))
|
||||
{
|
||||
gl_read_format = read_format;
|
||||
gl_read_type = read_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format, FALSE));
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&gl_internal_format, &gl_internal_srgb_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format, FALSE));
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
gdk_gl_context_get_use_es (context),
|
||||
&gl_internal_format, &gl_internal_srgb_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
|
||||
if (download->format == actual_format &&
|
||||
(download->stride == expected_stride))
|
||||
{
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
download->data);
|
||||
|
||||
gdk_memory_convert_color_state (download->data,
|
||||
download->stride,
|
||||
download->format,
|
||||
download->color_state,
|
||||
texture->color_state,
|
||||
texture->width,
|
||||
texture->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsize actual_bpp = gdk_memory_format_bytes_per_pixel (actual_format);
|
||||
gsize stride = actual_bpp * texture->width;
|
||||
guchar *pixels = g_malloc_n (stride, texture->height);
|
||||
|
||||
glPixelStorei (GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
pixels);
|
||||
|
||||
/* Fix up gles inadequacies */
|
||||
|
||||
if (gl_read_format == GL_RGBA &&
|
||||
gl_read_type == GL_UNSIGNED_BYTE &&
|
||||
(format == GDK_MEMORY_G8A8 ||
|
||||
format == GDK_MEMORY_G8A8_PREMULTIPLIED ||
|
||||
format == GDK_MEMORY_G8 ||
|
||||
format == GDK_MEMORY_A8))
|
||||
{
|
||||
for (unsigned int y = 0; y < texture->height; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < texture->width; x++)
|
||||
{
|
||||
guchar *data = &pixels[y * stride + x * actual_bpp];
|
||||
if (format == GDK_MEMORY_G8A8 ||
|
||||
format == GDK_MEMORY_G8A8_PREMULTIPLIED)
|
||||
{
|
||||
data[3] = data[1];
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
}
|
||||
else if (format == GDK_MEMORY_G8)
|
||||
{
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
data[3] = 0xff;
|
||||
}
|
||||
else if (format == GDK_MEMORY_A8)
|
||||
{
|
||||
data[3] = data[0];
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_read_format == GL_RGBA &&
|
||||
gl_read_type == GL_UNSIGNED_SHORT &&
|
||||
(format == GDK_MEMORY_G16A16 ||
|
||||
format == GDK_MEMORY_G16A16_PREMULTIPLIED ||
|
||||
format == GDK_MEMORY_G16 ||
|
||||
format == GDK_MEMORY_A16))
|
||||
{
|
||||
for (unsigned int y = 0; y < texture->height; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < texture->width; x++)
|
||||
{
|
||||
guint16 *data = (guint16 *) &pixels[y * stride + x * actual_bpp];
|
||||
if (format == GDK_MEMORY_G16A16 ||
|
||||
format == GDK_MEMORY_G16A16_PREMULTIPLIED)
|
||||
{
|
||||
data[3] = data[1];
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
}
|
||||
else if (format == GDK_MEMORY_G16)
|
||||
{
|
||||
data[1] = data[0];
|
||||
data[2] = data[0];
|
||||
data[3] = 0xffff;
|
||||
}
|
||||
else if (format == GDK_MEMORY_A16)
|
||||
{
|
||||
data[3] = data[0];
|
||||
data[0] = 0;
|
||||
data[1] = 0;
|
||||
data[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gdk_memory_convert (download->data,
|
||||
download->stride,
|
||||
download->format,
|
||||
download->color_state,
|
||||
pixels,
|
||||
stride,
|
||||
actual_format,
|
||||
texture->color_state,
|
||||
texture->width,
|
||||
texture->height);
|
||||
|
||||
g_free (pixels);
|
||||
}
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers (1, &fbo);
|
||||
}
|
||||
gdk_gl_context_download (context,
|
||||
gdk_gl_texture_get_id (self),
|
||||
gdk_texture_get_format (texture),
|
||||
gdk_texture_get_color_state (texture),
|
||||
download->data,
|
||||
download->stride,
|
||||
download->format,
|
||||
download->color_state,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdk_gl_texture_download (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
@@ -527,8 +277,7 @@ gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
|
||||
self->id = gdk_gl_texture_builder_get_id (builder);
|
||||
GDK_TEXTURE (self)->format = gdk_gl_texture_builder_get_format (builder);
|
||||
self->has_mipmap = gdk_gl_texture_builder_get_has_mipmap (builder);
|
||||
if (gdk_gl_context_has_feature (self->context, GDK_GL_FEATURE_SYNC))
|
||||
self->sync = gdk_gl_texture_builder_get_sync (builder);
|
||||
self->sync = gdk_gl_texture_builder_get_sync (builder);
|
||||
self->destroy = destroy;
|
||||
self->data = data;
|
||||
|
||||
|
||||
@@ -33,13 +33,9 @@ G_BEGIN_DECLS
|
||||
|
||||
/* Minimum OpenGL versions supported by GTK.
|
||||
* Backends should make sure to never create a context of a previous version.
|
||||
*
|
||||
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
|
||||
* OPENGL_PROFILE_MASK; and OpenGL ES respectively
|
||||
*/
|
||||
#define GDK_GL_MIN_GL_VERSION GDK_GL_VERSION_INIT (3, 2)
|
||||
#define GDK_GL_MIN_GL_LEGACY_VERSION GDK_GL_VERSION_INIT (3, 0)
|
||||
#define GDK_GL_MIN_GLES_VERSION GDK_GL_VERSION_INIT (2, 0)
|
||||
#define GDK_GL_MIN_GL_VERSION GDK_GL_VERSION_INIT (3, 3)
|
||||
#define GDK_GL_MIN_GLES_VERSION GDK_GL_VERSION_INIT (3, 0)
|
||||
|
||||
typedef struct _GdkGLVersion GdkGLVersion;
|
||||
|
||||
@@ -60,9 +56,6 @@ static const GdkGLVersion supported_gl_versions[] = {
|
||||
GDK_GL_VERSION_INIT (4, 1),
|
||||
GDK_GL_VERSION_INIT (4, 0),
|
||||
GDK_GL_VERSION_INIT (3, 3),
|
||||
GDK_GL_VERSION_INIT (3, 2),
|
||||
GDK_GL_VERSION_INIT (3, 1),
|
||||
GDK_GL_VERSION_INIT (3, 0),
|
||||
|
||||
GDK_GL_VERSION_INIT (0, 0)
|
||||
};
|
||||
@@ -71,7 +64,6 @@ static const GdkGLVersion supported_gles_versions[] = {
|
||||
GDK_GL_VERSION_INIT (3, 2),
|
||||
GDK_GL_VERSION_INIT (3, 1),
|
||||
GDK_GL_VERSION_INIT (3, 0),
|
||||
GDK_GL_VERSION_INIT (2, 0),
|
||||
|
||||
GDK_GL_VERSION_INIT (0, 0)
|
||||
};
|
||||
|
||||
@@ -2479,8 +2479,8 @@ void
|
||||
gdk_memory_convert_color_state (guchar *data,
|
||||
gsize stride,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorState *src_cs,
|
||||
GdkColorState *dest_cs,
|
||||
GdkColorState *src_color_state,
|
||||
GdkColorState *dest_color_state,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
@@ -2488,24 +2488,24 @@ gdk_memory_convert_color_state (guchar *data,
|
||||
.data = data,
|
||||
.stride = stride,
|
||||
.format = format,
|
||||
.src_cs = src_cs,
|
||||
.dest_cs = dest_cs,
|
||||
.src_cs = src_color_state,
|
||||
.dest_cs = dest_color_state,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
if (gdk_color_state_equal (src_cs, dest_cs))
|
||||
if (gdk_color_state_equal (src_color_state, dest_color_state))
|
||||
return;
|
||||
|
||||
if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
|
||||
src_cs == GDK_COLOR_STATE_SRGB &&
|
||||
dest_cs == GDK_COLOR_STATE_SRGB_LINEAR)
|
||||
src_color_state == GDK_COLOR_STATE_SRGB &&
|
||||
dest_color_state == GDK_COLOR_STATE_SRGB_LINEAR)
|
||||
{
|
||||
gdk_parallel_task_run (gdk_memory_convert_color_state_srgb_to_srgb_linear, &mc);
|
||||
}
|
||||
else if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
|
||||
src_cs == GDK_COLOR_STATE_SRGB_LINEAR &&
|
||||
dest_cs == GDK_COLOR_STATE_SRGB)
|
||||
src_color_state == GDK_COLOR_STATE_SRGB_LINEAR &&
|
||||
dest_color_state == GDK_COLOR_STATE_SRGB)
|
||||
{
|
||||
gdk_parallel_task_run (gdk_memory_convert_color_state_srgb_linear_to_srgb, &mc);
|
||||
}
|
||||
|
||||
@@ -96,11 +96,11 @@ const char * gdk_memory_format_get_name (GdkMemoryFormat
|
||||
void gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat dest_format,
|
||||
GdkColorState *src_cs,
|
||||
GdkColorState *dest_cs,
|
||||
const guchar *src_data,
|
||||
gsize src_stride,
|
||||
GdkMemoryFormat src_format,
|
||||
GdkColorState *dest_cs,
|
||||
GdkColorState *src_cs,
|
||||
gsize width,
|
||||
gsize height);
|
||||
void gdk_memory_convert_color_state (guchar *data,
|
||||
|
||||
+21
-104
@@ -35,7 +35,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
static const GdkDebugKey gdk_vulkan_feature_keys[] = {
|
||||
static const GdkDebugKey gsk_vulkan_feature_keys[] = {
|
||||
{ "dmabuf", GDK_VULKAN_FEATURE_DMABUF, "Never import Dmabufs" },
|
||||
{ "ycbcr", GDK_VULKAN_FEATURE_YCBCR, "Do not support Ycbcr textures (also disables dmabufs)" },
|
||||
{ "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" },
|
||||
@@ -419,10 +419,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
VkDevice device;
|
||||
guint i;
|
||||
|
||||
GDK_DEBUG (VULKAN, "(Re)creating the swapchain for surface of size %dx%d",
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface));
|
||||
|
||||
device = gdk_vulkan_context_get_device (context);
|
||||
|
||||
/*
|
||||
@@ -460,10 +456,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
|
||||
GDK_DEBUG (VULKAN, "Using surface present mode %s",
|
||||
surface_present_mode_to_string (present_mode));
|
||||
GDK_DEBUG (VULKAN, "Using extent %dx%d",
|
||||
capabilities.currentExtent.width,
|
||||
capabilities.currentExtent.height);
|
||||
|
||||
|
||||
/*
|
||||
* Per https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#VkSurfaceCapabilitiesKHR
|
||||
@@ -476,10 +468,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
|
||||
capabilities.currentExtent.width = MAX (1, (int) ceil (gdk_surface_get_width (surface) * scale));
|
||||
capabilities.currentExtent.height = MAX (1, (int) ceil (gdk_surface_get_height (surface) * scale));
|
||||
|
||||
GDK_DEBUG (VULKAN, "Effective extent %dx%d",
|
||||
capabilities.currentExtent.width,
|
||||
capabilities.currentExtent.height);
|
||||
}
|
||||
|
||||
res = GDK_VK_CHECK (vkCreateSwapchainKHR, device,
|
||||
@@ -566,20 +554,12 @@ physical_device_supports_extension (VkPhysicalDevice device,
|
||||
{
|
||||
VkExtensionProperties *extensions;
|
||||
uint32_t n_device_extensions;
|
||||
static gboolean first = TRUE;
|
||||
|
||||
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, NULL);
|
||||
|
||||
extensions = g_newa (VkExtensionProperties, n_device_extensions);
|
||||
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, extensions);
|
||||
|
||||
if (first)
|
||||
{
|
||||
first = FALSE;
|
||||
for (uint32_t i = 0; i < n_device_extensions; i++)
|
||||
g_print ("%s\n", extensions[i].extensionName);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < n_device_extensions; i++)
|
||||
{
|
||||
if (g_str_equal (extensions[i].extensionName, extension_name))
|
||||
@@ -706,37 +686,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (acquire_result == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
const VkPipelineStageFlags mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
|
||||
vkQueueSubmit (gdk_vulkan_context_get_queue (context),
|
||||
1,
|
||||
&(VkSubmitInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &priv->draw_semaphore,
|
||||
.pWaitDstStageMask = &mask,
|
||||
},
|
||||
VK_NULL_HANDLE);
|
||||
vkQueueWaitIdle (gdk_vulkan_context_get_queue (context));
|
||||
|
||||
if (gdk_vulkan_context_has_feature (context, GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE))
|
||||
{
|
||||
PFN_vkReleaseSwapchainImagesEXT vkReleaseSwapchainImagesEXT;
|
||||
|
||||
vkReleaseSwapchainImagesEXT = (PFN_vkReleaseSwapchainImagesEXT) vkGetDeviceProcAddr (gdk_vulkan_context_get_device (context), "vkReleaseSwapchainImagesEXT");
|
||||
|
||||
vkReleaseSwapchainImagesEXT (gdk_vulkan_context_get_device (context),
|
||||
&(VkReleaseSwapchainImagesInfoEXT) {
|
||||
.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT,
|
||||
.pNext = NULL,
|
||||
.swapchain = priv->swapchain,
|
||||
.imageIndexCount = 1,
|
||||
.pImageIndices = &priv->draw_index,
|
||||
});
|
||||
}
|
||||
}
|
||||
GDK_DEBUG (VULKAN, "Recreating the swapchain");
|
||||
|
||||
if (gdk_vulkan_context_check_swapchain (context, &error))
|
||||
continue;
|
||||
@@ -1455,9 +1405,6 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
{
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
uint32_t i, j, k;
|
||||
const char *override;
|
||||
gboolean list_devices;
|
||||
int first, last;
|
||||
GdkVulkanFeatures skip_features;
|
||||
|
||||
uint32_t n_devices = 0;
|
||||
@@ -1475,45 +1422,14 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
devices = g_newa (VkPhysicalDevice, n_devices);
|
||||
GDK_VK_CHECK(vkEnumeratePhysicalDevices, display->vk_instance, &n_devices, devices);
|
||||
|
||||
first = 0;
|
||||
last = n_devices;
|
||||
|
||||
skip_features = gdk_parse_debug_var ("GDK_VULKAN_DISABLE",
|
||||
"GDK_VULKAN_DISABLE can be set to a list of Vulkan features to disable.\n",
|
||||
gdk_vulkan_feature_keys,
|
||||
G_N_ELEMENTS (gdk_vulkan_feature_keys));
|
||||
gsk_vulkan_feature_keys,
|
||||
G_N_ELEMENTS (gsk_vulkan_feature_keys));
|
||||
if (skip_features & GDK_VULKAN_FEATURE_YCBCR)
|
||||
skip_features |= GDK_VULKAN_FEATURE_DMABUF;
|
||||
|
||||
override = g_getenv ("GDK_VULKAN_DEVICE");
|
||||
list_devices = FALSE;
|
||||
if (override)
|
||||
{
|
||||
if (g_strcmp0 (override, "list") == 0)
|
||||
list_devices = TRUE;
|
||||
else
|
||||
{
|
||||
gint64 device_idx;
|
||||
GError *error2 = NULL;
|
||||
|
||||
if (!g_ascii_string_to_signed (override, 10, 0, G_MAXINT, &device_idx, &error2))
|
||||
{
|
||||
g_warning ("Failed to parse %s: %s", "GDK_VULKAN_DEVICE", error2->message);
|
||||
g_error_free (error2);
|
||||
device_idx = -1;
|
||||
}
|
||||
|
||||
if (device_idx < 0 || device_idx >= n_devices)
|
||||
g_warning ("%s value out of range, ignoring", "GDK_VULKAN_DEVICE");
|
||||
else
|
||||
{
|
||||
first = device_idx;
|
||||
last = first + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (list_devices || GDK_DISPLAY_DEBUG_CHECK (display, VULKAN))
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, VULKAN))
|
||||
{
|
||||
for (i = 0; i < n_devices; i++)
|
||||
{
|
||||
@@ -1564,7 +1480,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
for (i = first; i < last; i++)
|
||||
for (i = 0; i < n_devices; i++)
|
||||
{
|
||||
GdkVulkanFeatures features, device_features;
|
||||
uint32_t n_queue_props;
|
||||
@@ -1580,7 +1496,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
{
|
||||
if (queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = {
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT,
|
||||
.swapchainMaintenance1 = VK_TRUE,
|
||||
};
|
||||
@@ -1656,13 +1572,13 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
display->vulkan_features = features;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, VULKAN, "Enabled features (use GDK_VULKAN_DISABLE env var to disable):");
|
||||
for (i = 0; i < G_N_ELEMENTS (gdk_vulkan_feature_keys); i++)
|
||||
for (i = 0; i < G_N_ELEMENTS (gsk_vulkan_feature_keys); i++)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, VULKAN, " %s: %s",
|
||||
gdk_vulkan_feature_keys[i].key,
|
||||
(features & gdk_vulkan_feature_keys[i].value) ? "✓" :
|
||||
((skip_features & gdk_vulkan_feature_keys[i].value) ? "disabled via env var" :
|
||||
(((device_features & gdk_vulkan_feature_keys[i].value) == 0) ? "✗" :
|
||||
gsk_vulkan_feature_keys[i].key,
|
||||
(features & gsk_vulkan_feature_keys[i].value) ? "YES" :
|
||||
((skip_features & gsk_vulkan_feature_keys[i].value) ? "disabled via env var" :
|
||||
(((device_features & gsk_vulkan_feature_keys[i].value) == 0) ? "not supported" :
|
||||
"Hum, what? This should not happen.")));
|
||||
}
|
||||
|
||||
@@ -1995,19 +1911,20 @@ gdk_vulkan_init_dmabuf (GdkDisplay *display)
|
||||
g_warn_if_fail (modifier_props.drmFormatModifierCount < sizeof (modifier_list));
|
||||
for (j = 0; j < modifier_props.drmFormatModifierCount; j++)
|
||||
{
|
||||
gboolean advertise = modifier_list[j].drmFormatModifier != DRM_FORMAT_MOD_LINEAR;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Vulkan supports dmabuf format %.4s::%016llx with %u planes and features 0x%x",
|
||||
"Vulkan %s dmabuf format %.4s::%016"G_GINT64_MODIFIER"x with %u planes and features 0x%x",
|
||||
advertise ? "advertises" : "supports",
|
||||
(char *) &fourcc,
|
||||
(long long unsigned) modifier_list[j].drmFormatModifier,
|
||||
modifier_list[j].drmFormatModifier,
|
||||
modifier_list[j].drmFormatModifierPlaneCount,
|
||||
modifier_list[j].drmFormatModifierTilingFeatures);
|
||||
|
||||
if (modifier_list[j].drmFormatModifier == DRM_FORMAT_MOD_LINEAR)
|
||||
continue;
|
||||
|
||||
gdk_dmabuf_formats_builder_add_format (vulkan_builder,
|
||||
fourcc,
|
||||
modifier_list[j].drmFormatModifier);
|
||||
if (advertise)
|
||||
gdk_dmabuf_formats_builder_add_format (vulkan_builder,
|
||||
fourcc,
|
||||
modifier_list[j].drmFormatModifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ print ";\n\n";
|
||||
|
||||
print <<EOT;
|
||||
typedef struct {
|
||||
guint keyval;
|
||||
guint offset;
|
||||
unsigned int keyval;
|
||||
unsigned int offset;
|
||||
} gdk_key;
|
||||
|
||||
static const gdk_key gdk_keys_by_keyval[] = {
|
||||
|
||||
@@ -42,12 +42,6 @@
|
||||
#define siglongjmp longjmp
|
||||
#endif
|
||||
|
||||
#define JPEG_MEM_DEST_USES_SIZE_T \
|
||||
(!(LIBJPEG_TURBO_VERSION_NUMBER) && \
|
||||
(((JPEG_LIB_VERSION) > 90) || \
|
||||
((JPEG_LIB_VERSION) == 90 && (JPEG_LIB_VERSION_MAJOR) > 9) || \
|
||||
((JPEG_LIB_VERSION) == 90 && (JPEG_LIB_VERSION_MAJOR) == 9 && (JPEG_LIB_VERSION_MINOR) > 3)))
|
||||
|
||||
struct error_handler_data {
|
||||
struct jpeg_error_mgr pub;
|
||||
sigjmp_buf setjmp_buffer;
|
||||
@@ -237,11 +231,7 @@ gdk_save_jpeg (GdkTexture *texture)
|
||||
struct error_handler_data jerr;
|
||||
struct jpeg_error_mgr err;
|
||||
guchar *data = NULL;
|
||||
#if JPEG_MEM_DEST_USES_SIZE_T
|
||||
gsize size = 0;
|
||||
#else
|
||||
gulong size = 0;
|
||||
#endif
|
||||
guchar *input = NULL;
|
||||
GdkTextureDownloader downloader;
|
||||
GBytes *texbytes = NULL;
|
||||
|
||||
@@ -146,6 +146,14 @@ typedef NSString *CALayerContentsGravity;
|
||||
inManualResize = NO;
|
||||
inMove = NO;
|
||||
|
||||
/* We need to deliver the event to the proper drag gestures or we
|
||||
* will leave the window in inconsistent state that requires clicking
|
||||
* in the window to cancel the gesture.
|
||||
*
|
||||
* TODO: Can we improve grab breaking to fix this?
|
||||
*/
|
||||
_gdk_macos_display_send_event ([self gdkDisplay], event);
|
||||
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
|
||||
|
||||
/* Reset gravity */
|
||||
|
||||
@@ -270,6 +270,13 @@ gdk_macos_display_get_next_serial (GdkDisplay *display)
|
||||
return ++serial;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_display_has_pending (GdkDisplay *display)
|
||||
{
|
||||
return _gdk_event_queue_find_first (display) ||
|
||||
_gdk_macos_event_source_check_pending ();
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_notify_startup_complete (GdkDisplay *display,
|
||||
const char *startup_notification_id)
|
||||
@@ -604,6 +611,7 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
|
||||
display_class->get_next_serial = gdk_macos_display_get_next_serial;
|
||||
display_class->get_name = gdk_macos_display_get_name;
|
||||
display_class->get_setting = gdk_macos_display_get_setting;
|
||||
display_class->has_pending = gdk_macos_display_has_pending;
|
||||
display_class->init_gl = gdk_macos_display_init_gl;
|
||||
display_class->notify_startup_complete = gdk_macos_display_notify_startup_complete;
|
||||
display_class->queue_events = gdk_macos_display_queue_events;
|
||||
|
||||
@@ -391,7 +391,7 @@ _gdk_macos_pasteboard_register_drag_types (NSWindow *window)
|
||||
/* Default to an url type (think gobject://internal)
|
||||
* to support internal, GType-based DnD.
|
||||
*/
|
||||
if ([ret count] == 0)
|
||||
if (n_mime_types == 0)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
gsize n_gtypes;
|
||||
|
||||
@@ -208,21 +208,16 @@ wl_cursor_destroy(struct wl_cursor *cursor)
|
||||
static struct wl_cursor *
|
||||
wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int size,
|
||||
unsigned int scale)
|
||||
unsigned int size)
|
||||
{
|
||||
char *path;
|
||||
XcursorImages *images;
|
||||
struct wl_cursor *cursor;
|
||||
struct cursor_image *image;
|
||||
int i, nbytes;
|
||||
unsigned int load_size;
|
||||
int load_scale = 1;
|
||||
|
||||
load_size = size * scale;
|
||||
|
||||
path = g_strconcat (theme->path, "/", name, NULL);
|
||||
images = xcursor_load_images (path, load_size);
|
||||
images = xcursor_load_images (path, size);
|
||||
|
||||
if (!images)
|
||||
{
|
||||
@@ -230,14 +225,6 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (images->images[0]->width != load_size ||
|
||||
images->images[0]->height != load_size)
|
||||
{
|
||||
xcursor_images_destroy (images);
|
||||
images = xcursor_load_images (path, size);
|
||||
load_scale = scale;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
|
||||
cursor = malloc(sizeof *cursor);
|
||||
@@ -255,7 +242,7 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
|
||||
}
|
||||
|
||||
cursor->name = strdup(name);
|
||||
cursor->size = load_size;
|
||||
cursor->size = images->images[0]->size;
|
||||
|
||||
for (i = 0; i < images->nimage; i++) {
|
||||
image = malloc(sizeof *image);
|
||||
@@ -265,10 +252,10 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
|
||||
image->theme = theme;
|
||||
image->buffer = NULL;
|
||||
|
||||
image->image.width = images->images[i]->width * load_scale;
|
||||
image->image.height = images->images[i]->height * load_scale;
|
||||
image->image.hotspot_x = images->images[i]->xhot * load_scale;
|
||||
image->image.hotspot_y = images->images[i]->yhot * load_scale;
|
||||
image->image.width = images->images[i]->width;
|
||||
image->image.height = images->images[i]->height;
|
||||
image->image.hotspot_x = images->images[i]->xhot;
|
||||
image->image.hotspot_y = images->images[i]->yhot;
|
||||
image->image.delay = images->images[i]->delay;
|
||||
|
||||
nbytes = image->image.width * image->image.height * 4;
|
||||
@@ -278,24 +265,9 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
|
||||
break;
|
||||
}
|
||||
|
||||
if (load_scale == 1) {
|
||||
/* copy pixels to shm pool */
|
||||
memcpy(theme->pool->data + image->offset,
|
||||
images->images[i]->pixels, nbytes);
|
||||
}
|
||||
else {
|
||||
/* scale image up while copying it */
|
||||
for (int y = 0; y < image->image.height; y++) {
|
||||
char *p = theme->pool->data + image->offset + y * image->image.width * 4;
|
||||
char *q = ((char *)images->images[i]->pixels) + (y / load_scale) * images->images[i]->width * 4;
|
||||
for (int x = 0; x < image->image.width; x++) {
|
||||
p[4 * x] = q[4 * (x/load_scale)];
|
||||
p[4 * x + 1] = q[4 * (x/load_scale) + 1];
|
||||
p[4 * x + 2] = q[4 * (x/load_scale) + 2];
|
||||
p[4 * x + 3] = q[4 * (x/load_scale) + 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* copy pixels to shm pool */
|
||||
memcpy(theme->pool->data + image->offset,
|
||||
images->images[i]->pixels, nbytes);
|
||||
cursor->images[i] = (struct wl_cursor_image *) image;
|
||||
}
|
||||
cursor->image_count = i;
|
||||
@@ -316,12 +288,11 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
|
||||
static void
|
||||
load_cursor(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int size,
|
||||
unsigned int scale)
|
||||
unsigned int size)
|
||||
{
|
||||
struct wl_cursor *cursor;
|
||||
|
||||
cursor = wl_cursor_create_from_xcursor_images(theme, name, size, scale);
|
||||
cursor = wl_cursor_create_from_xcursor_images(theme, name, size);
|
||||
|
||||
if (cursor) {
|
||||
theme->cursor_count++;
|
||||
@@ -405,12 +376,12 @@ wl_cursor_theme_destroy(struct wl_cursor_theme *theme)
|
||||
struct wl_cursor *
|
||||
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int scale)
|
||||
float scale)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int size;
|
||||
|
||||
size = theme->size * scale;
|
||||
size = ceil (theme->size * scale);
|
||||
|
||||
for (i = 0; i < theme->cursor_count; i++) {
|
||||
if (size == theme->cursors[i]->size &&
|
||||
@@ -418,11 +389,10 @@ wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
||||
return theme->cursors[i];
|
||||
}
|
||||
|
||||
load_cursor (theme, name, theme->size, scale);
|
||||
load_cursor (theme, name, size);
|
||||
|
||||
if (i < theme->cursor_count) {
|
||||
if (size == theme->cursors[i]->size &&
|
||||
strcmp (name, theme->cursors[theme->cursor_count - 1]->name) == 0)
|
||||
if (strcmp (name, theme->cursors[theme->cursor_count - 1]->name) == 0)
|
||||
return theme->cursors[theme->cursor_count - 1];
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ wl_cursor_theme_destroy(struct wl_cursor_theme *theme);
|
||||
struct wl_cursor *
|
||||
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int scale);
|
||||
float scale);
|
||||
|
||||
struct wl_buffer *
|
||||
wl_cursor_image_get_buffer(struct wl_cursor_image *image);
|
||||
|
||||
@@ -402,6 +402,38 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader,
|
||||
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
|
||||
continue;
|
||||
thisSize = fileHeader->tocs[n].subtype;
|
||||
if (thisSize == size)
|
||||
{
|
||||
bestSize = size;
|
||||
nsizes++;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestSize)
|
||||
goto done;
|
||||
|
||||
for (n = 0; n < fileHeader->ntoc; n++)
|
||||
{
|
||||
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
|
||||
continue;
|
||||
thisSize = fileHeader->tocs[n].subtype;
|
||||
if (thisSize == 2 * size)
|
||||
{
|
||||
bestSize = 2 * size;
|
||||
nsizes++;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestSize)
|
||||
goto done;
|
||||
|
||||
for (n = 0; n < fileHeader->ntoc; n++)
|
||||
{
|
||||
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
|
||||
continue;
|
||||
thisSize = fileHeader->tocs[n].subtype;
|
||||
if (thisSize < size)
|
||||
continue;
|
||||
if (!bestSize || dist (thisSize, size) < dist (bestSize, size))
|
||||
{
|
||||
bestSize = thisSize;
|
||||
@@ -410,6 +442,25 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader,
|
||||
else if (thisSize == bestSize)
|
||||
nsizes++;
|
||||
}
|
||||
|
||||
if (bestSize)
|
||||
goto done;
|
||||
|
||||
for (n = 0; n < fileHeader->ntoc; n++)
|
||||
{
|
||||
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
|
||||
continue;
|
||||
thisSize = fileHeader->tocs[n].subtype;
|
||||
if (!bestSize || dist (thisSize, size) < dist (bestSize, size))
|
||||
{
|
||||
bestSize = thisSize;
|
||||
nsizes = 1;
|
||||
}
|
||||
else if (thisSize == bestSize)
|
||||
nsizes++;
|
||||
}
|
||||
|
||||
done:
|
||||
*nsizesp = nsizes;
|
||||
return bestSize;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ name_fallback (const char *name)
|
||||
static struct wl_cursor *
|
||||
gdk_wayland_cursor_load_for_name (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_cursor_theme *theme,
|
||||
int scale,
|
||||
float scale,
|
||||
const char *name)
|
||||
{
|
||||
struct wl_cursor *c;
|
||||
@@ -156,7 +156,6 @@ struct wl_buffer *
|
||||
_gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
GdkCursor *cursor,
|
||||
double desired_scale,
|
||||
gboolean use_viewporter,
|
||||
guint image_index,
|
||||
int *hotspot_x,
|
||||
int *hotspot_y,
|
||||
@@ -169,7 +168,6 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
if (gdk_cursor_get_name (cursor))
|
||||
{
|
||||
struct wl_cursor *c;
|
||||
int scale_factor;
|
||||
|
||||
if (g_str_equal (gdk_cursor_get_name (cursor), "none"))
|
||||
{
|
||||
@@ -179,12 +177,11 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scale_factor = (int) ceil (desired_scale);
|
||||
|
||||
c = gdk_wayland_cursor_load_for_name (display,
|
||||
display->cursor_theme,
|
||||
scale_factor,
|
||||
desired_scale,
|
||||
gdk_cursor_get_name (cursor));
|
||||
|
||||
if (c && c->image_count > 0)
|
||||
{
|
||||
struct wl_cursor_image *image;
|
||||
@@ -199,22 +196,12 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
|
||||
image = c->images[image_index];
|
||||
|
||||
*width = display->cursor_theme_size;
|
||||
*height = display->cursor_theme_size;
|
||||
*scale = image->width / (double) *width;
|
||||
*hotspot_x = image->hotspot_x / scale_factor;
|
||||
*hotspot_y = image->hotspot_y / scale_factor;
|
||||
*scale = c->size / (double) display->cursor_theme_size;
|
||||
|
||||
if (*scale != scale_factor && !use_viewporter)
|
||||
{
|
||||
g_warning (G_STRLOC " cursor image size (%d) not an integer "
|
||||
"multiple of theme size (%d)", image->width, *width);
|
||||
*width = image->width;
|
||||
*height = image->height;
|
||||
*hotspot_x = image->hotspot_x;
|
||||
*hotspot_y = image->hotspot_y;
|
||||
*scale = 1;
|
||||
}
|
||||
*width = image->width / *scale;
|
||||
*height = image->height / *scale;
|
||||
*hotspot_x = image->hotspot_x / *scale;
|
||||
*hotspot_y = image->hotspot_y / *scale;
|
||||
|
||||
return wl_cursor_image_get_buffer (image);
|
||||
}
|
||||
@@ -260,14 +247,11 @@ from_texture:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!use_viewporter)
|
||||
*scale = ceil (desired_scale);
|
||||
else
|
||||
*scale = desired_scale;
|
||||
*scale = desired_scale;
|
||||
|
||||
texture = gdk_cursor_get_texture_for_size (cursor,
|
||||
display->cursor_theme_size,
|
||||
*scale,
|
||||
desired_scale,
|
||||
width,
|
||||
height,
|
||||
hotspot_x,
|
||||
@@ -302,7 +286,6 @@ from_texture:
|
||||
return _gdk_wayland_cursor_get_buffer (display,
|
||||
gdk_cursor_get_fallback (cursor),
|
||||
desired_scale,
|
||||
use_viewporter,
|
||||
image_index,
|
||||
hotspot_x, hotspot_y,
|
||||
width, height,
|
||||
|
||||
@@ -265,22 +265,17 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
|
||||
guint next_image_index, next_image_delay;
|
||||
gboolean retval = G_SOURCE_REMOVE;
|
||||
GdkWaylandTabletData *tablet;
|
||||
gboolean use_viewport = FALSE;
|
||||
|
||||
tablet = gdk_wayland_seat_find_tablet (seat, device);
|
||||
|
||||
if (pointer->pointer_surface_viewport &&
|
||||
g_getenv ("USE_POINTER_VIEWPORT"))
|
||||
use_viewport = TRUE;
|
||||
|
||||
if (pointer->cursor)
|
||||
{
|
||||
buffer = _gdk_wayland_cursor_get_buffer (GDK_WAYLAND_DISPLAY (seat->display),
|
||||
pointer->cursor,
|
||||
pointer->current_output_scale,
|
||||
use_viewport,
|
||||
pointer->cursor_image_index,
|
||||
&x, &y, &w, &h, &scale);
|
||||
&x, &y, &w, &h,
|
||||
&scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -317,7 +312,7 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
|
||||
if (buffer)
|
||||
{
|
||||
wl_surface_attach (pointer->pointer_surface, buffer, 0, 0);
|
||||
if (use_viewport)
|
||||
if (pointer->pointer_surface_viewport)
|
||||
{
|
||||
wp_viewport_set_source (pointer->pointer_surface_viewport,
|
||||
wl_fixed_from_int (0),
|
||||
@@ -326,8 +321,6 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
|
||||
wl_fixed_from_double (h * scale));
|
||||
wp_viewport_set_destination (pointer->pointer_surface_viewport, w, h);
|
||||
}
|
||||
else if (wl_surface_get_version (pointer->pointer_surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
|
||||
wl_surface_set_buffer_scale (pointer->pointer_surface, scale);
|
||||
wl_surface_damage (pointer->pointer_surface, 0, 0, w, h);
|
||||
wl_surface_commit (pointer->pointer_surface);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "gdksurface-wayland.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkcairocontext-wayland.h"
|
||||
@@ -623,7 +624,7 @@ _gdk_wayland_display_open (const char *display_name)
|
||||
display = g_object_new (GDK_TYPE_WAYLAND_DISPLAY, NULL);
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
display_wayland->wl_display = wl_display;
|
||||
gdk_wayland_display_install_gsources (display_wayland);
|
||||
display_wayland->event_source = _gdk_wayland_display_event_source_new (display);
|
||||
|
||||
init_settings (display);
|
||||
|
||||
@@ -724,7 +725,12 @@ gdk_wayland_display_dispose (GObject *object)
|
||||
|
||||
g_list_free_full (display_wayland->toplevels, destroy_toplevel);
|
||||
|
||||
gdk_wayland_display_uninstall_gsources (display_wayland);
|
||||
if (display_wayland->event_source)
|
||||
{
|
||||
g_source_destroy (display_wayland->event_source);
|
||||
g_source_unref (display_wayland->event_source);
|
||||
display_wayland->event_source = NULL;
|
||||
}
|
||||
|
||||
g_list_free_full (display_wayland->async_roundtrips, (GDestroyNotify) wl_callback_destroy);
|
||||
|
||||
@@ -876,6 +882,12 @@ gdk_wayland_display_make_default (GdkDisplay *display)
|
||||
display_wayland->startup_notification_id = g_strdup (startup_id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_display_has_pending (GdkDisplay *display)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gulong
|
||||
gdk_wayland_display_get_next_serial (GdkDisplay *display)
|
||||
{
|
||||
@@ -1042,6 +1054,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
display_class->sync = gdk_wayland_display_sync;
|
||||
display_class->flush = gdk_wayland_display_flush;
|
||||
display_class->make_default = gdk_wayland_display_make_default;
|
||||
display_class->has_pending = gdk_wayland_display_has_pending;
|
||||
display_class->queue_events = _gdk_wayland_display_queue_events;
|
||||
display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context;
|
||||
display_class->get_next_serial = gdk_wayland_display_get_next_serial;
|
||||
@@ -1151,6 +1164,7 @@ _gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY(display);
|
||||
struct wl_cursor_theme *theme;
|
||||
GList *seats;
|
||||
|
||||
g_assert (display_wayland);
|
||||
g_assert (display_wayland->shm);
|
||||
@@ -1180,6 +1194,15 @@ _gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
g_free (display_wayland->cursor_theme_name);
|
||||
display_wayland->cursor_theme_name = g_strdup (name);
|
||||
display_wayland->cursor_theme_size = size;
|
||||
|
||||
seats = gdk_display_list_seats (display);
|
||||
for (GList *l = seats; l; l = l->next)
|
||||
{
|
||||
GdkSeat *seat = l->data;
|
||||
|
||||
gdk_wayland_device_update_surface_cursor (gdk_seat_get_pointer (seat));
|
||||
}
|
||||
g_list_free (seats);
|
||||
}
|
||||
|
||||
struct wl_cursor_theme *
|
||||
|
||||
@@ -146,7 +146,6 @@ struct _GdkWaylandDisplay
|
||||
GHashTable *cursor_surface_cache;
|
||||
|
||||
GSource *event_source;
|
||||
GSource *poll_source;
|
||||
|
||||
uint32_t server_decoration_mode;
|
||||
|
||||
|
||||
+81
-173
@@ -24,119 +24,44 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef struct _GdkWaylandEventSource GdkWaylandEventSource;
|
||||
typedef struct _GdkWaylandPollSource GdkWaylandPollSource;
|
||||
|
||||
struct _GdkWaylandEventSource
|
||||
{
|
||||
GSource source;
|
||||
GdkWaylandDisplay *display;
|
||||
};
|
||||
|
||||
struct _GdkWaylandPollSource
|
||||
{
|
||||
typedef struct _GdkWaylandEventSource {
|
||||
GSource source;
|
||||
GPollFD pfd;
|
||||
GdkWaylandDisplay *display;
|
||||
guint reading : 1;
|
||||
guint can_dispatch : 1;
|
||||
};
|
||||
|
||||
/* If we should try wl_display_dispatch_pending() before
|
||||
* polling the Wayland fd
|
||||
*/
|
||||
static gboolean
|
||||
gdk_wayland_display_can_dispatch (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
GdkWaylandPollSource *poll_source = (GdkWaylandPollSource *) display_wayland->poll_source;
|
||||
|
||||
return poll_source->can_dispatch;
|
||||
}
|
||||
|
||||
/* If we still have events to process and don't need to poll */
|
||||
static gboolean
|
||||
gdk_wayland_display_has_events_pending (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
return gdk_wayland_display_can_dispatch (display_wayland) ||
|
||||
_gdk_event_queue_find_first (GDK_DISPLAY (display_wayland)) != NULL;
|
||||
}
|
||||
uint32_t mask;
|
||||
GdkDisplay *display;
|
||||
gboolean reading;
|
||||
} GdkWaylandEventSource;
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_event_source_prepare (GSource *base,
|
||||
int *timeout)
|
||||
gdk_event_source_prepare (GSource *base,
|
||||
int *timeout)
|
||||
{
|
||||
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
return gdk_wayland_display_has_events_pending (source->display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_event_source_check (GSource *base)
|
||||
{
|
||||
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
|
||||
|
||||
return gdk_wayland_display_has_events_pending (source->display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_event_source_dispatch (GSource *base,
|
||||
GSourceFunc callback,
|
||||
gpointer data)
|
||||
{
|
||||
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_display_get_event (GDK_DISPLAY (source->display));
|
||||
|
||||
if (event)
|
||||
{
|
||||
_gdk_event_emit (event);
|
||||
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_event_source_finalize (GSource *base)
|
||||
{
|
||||
}
|
||||
|
||||
static GSourceFuncs gdk_wayland_event_source_funcs = {
|
||||
gdk_wayland_event_source_prepare,
|
||||
gdk_wayland_event_source_check,
|
||||
gdk_wayland_event_source_dispatch,
|
||||
gdk_wayland_event_source_finalize
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_poll_source_prepare (GSource *base,
|
||||
int *timeout)
|
||||
{
|
||||
GdkWaylandPollSource *source = (GdkWaylandPollSource *) base;
|
||||
GdkWaylandDisplay *display = (GdkWaylandDisplay *) source->display;
|
||||
GList *l;
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
if (gdk_wayland_display_has_events_pending (source->display))
|
||||
return FALSE;
|
||||
if (source->display->event_pause_count > 0)
|
||||
return _gdk_event_queue_find_first (source->display) != NULL;
|
||||
|
||||
/* We have to add/remove the GPollFD if we want to update our
|
||||
* poll event mask dynamically. Instead, let's just flush all
|
||||
* write on idle instead, which is what this amounts to.
|
||||
*/
|
||||
|
||||
if (_gdk_event_queue_find_first (source->display) != NULL)
|
||||
return TRUE;
|
||||
|
||||
/* wl_display_prepare_read() needs to be balanced with either
|
||||
* wl_display_read_events() or wl_display_cancel_read()
|
||||
* (in gdk_wayland_event_source_check() */
|
||||
* (in gdk_event_source_check() */
|
||||
if (source->reading)
|
||||
return FALSE;
|
||||
|
||||
/* if prepare_read() returns non-zero, there are events to be dispatched */
|
||||
if (wl_display_prepare_read (display->wl_display) != 0)
|
||||
{
|
||||
source->can_dispatch = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
/* We need to check whether there are pending events on the surface queues as well,
|
||||
* but we also need to make sure to only have one active "read" in the end,
|
||||
@@ -149,8 +74,6 @@ gdk_wayland_poll_source_prepare (GSource *base,
|
||||
|
||||
if (wl_display_prepare_read_queue (display->wl_display, queue) != 0)
|
||||
{
|
||||
source->can_dispatch = TRUE;
|
||||
/* cancel the read from before the for loop */
|
||||
wl_display_cancel_read (display->wl_display);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -169,19 +92,23 @@ gdk_wayland_poll_source_prepare (GSource *base,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_poll_source_check (GSource *base)
|
||||
gdk_event_source_check (GSource *base)
|
||||
{
|
||||
GdkWaylandPollSource *source = (GdkWaylandPollSource *) base;
|
||||
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
|
||||
GdkWaylandDisplay *display_wayland = (GdkWaylandDisplay *) source->display;
|
||||
|
||||
if (source->display->event_pause_count > 0)
|
||||
{
|
||||
if (source->reading)
|
||||
wl_display_cancel_read (display_wayland->wl_display);
|
||||
source->reading = FALSE;
|
||||
|
||||
return _gdk_event_queue_find_first (source->display) != NULL;
|
||||
}
|
||||
|
||||
/* read the events from the wayland fd into their respective queues if we have data */
|
||||
if (source->reading)
|
||||
{
|
||||
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
|
||||
{
|
||||
g_message ("Lost connection to Wayland compositor.");
|
||||
_exit (1);
|
||||
}
|
||||
if (source->pfd.revents & G_IO_IN)
|
||||
{
|
||||
if (wl_display_read_events (display_wayland->wl_display) < 0)
|
||||
@@ -189,40 +116,53 @@ gdk_wayland_poll_source_check (GSource *base)
|
||||
g_message ("Error reading events from display: %s", g_strerror (errno));
|
||||
_exit (1);
|
||||
}
|
||||
source->pfd.revents = 0;
|
||||
source->can_dispatch = TRUE;
|
||||
}
|
||||
else
|
||||
wl_display_cancel_read (display_wayland->wl_display);
|
||||
source->reading = FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return _gdk_event_queue_find_first (source->display) != NULL ||
|
||||
source->pfd.revents;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_poll_source_dispatch (GSource *base,
|
||||
GSourceFunc callback,
|
||||
gpointer data)
|
||||
gdk_event_source_dispatch (GSource *base,
|
||||
GSourceFunc callback,
|
||||
gpointer data)
|
||||
{
|
||||
return G_SOURCE_CONTINUE;
|
||||
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
|
||||
GdkDisplay *display = source->display;
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_display_get_event (display);
|
||||
|
||||
if (event)
|
||||
{
|
||||
_gdk_event_emit (event);
|
||||
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_poll_source_finalize (GSource *base)
|
||||
gdk_event_source_finalize (GSource *base)
|
||||
{
|
||||
GdkWaylandPollSource *source = (GdkWaylandPollSource *) base;
|
||||
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
|
||||
GdkWaylandDisplay *display = (GdkWaylandDisplay *) source->display;
|
||||
|
||||
if (source->reading)
|
||||
wl_display_cancel_read (source->display->wl_display);
|
||||
wl_display_cancel_read (display->wl_display);
|
||||
source->reading = FALSE;
|
||||
}
|
||||
|
||||
static GSourceFuncs gdk_wayland_poll_source_funcs = {
|
||||
gdk_wayland_poll_source_prepare,
|
||||
gdk_wayland_poll_source_check,
|
||||
gdk_wayland_poll_source_dispatch,
|
||||
gdk_wayland_poll_source_finalize
|
||||
static GSourceFuncs wl_glib_source_funcs = {
|
||||
gdk_event_source_prepare,
|
||||
gdk_event_source_check,
|
||||
gdk_event_source_dispatch,
|
||||
gdk_event_source_finalize
|
||||
};
|
||||
|
||||
void
|
||||
@@ -236,81 +176,45 @@ _gdk_wayland_display_deliver_event (GdkDisplay *display,
|
||||
_gdk_display_get_next_serial (display));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_display_install_gsources (GdkWaylandDisplay *display_wayland)
|
||||
GSource *
|
||||
_gdk_wayland_display_event_source_new (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplay *display = GDK_DISPLAY (display_wayland);
|
||||
GSource *source;
|
||||
GdkWaylandEventSource *event_source;
|
||||
GdkWaylandPollSource *poll_source;
|
||||
GdkWaylandEventSource *wl_source;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
char *name;
|
||||
|
||||
/* SOURCE 1 */
|
||||
source = g_source_new (&gdk_wayland_event_source_funcs,
|
||||
source = g_source_new (&wl_glib_source_funcs,
|
||||
sizeof (GdkWaylandEventSource));
|
||||
display_wayland->event_source = source;
|
||||
event_source = (GdkWaylandEventSource *) source;
|
||||
name = g_strdup_printf ("GDK Wayland Event source (%s)",
|
||||
gdk_display_get_name (display));
|
||||
g_source_set_name (source, name);
|
||||
g_free (name);
|
||||
wl_source = (GdkWaylandEventSource *) source;
|
||||
|
||||
event_source->display = display_wayland;
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
wl_source->display = display;
|
||||
wl_source->pfd.fd = wl_display_get_fd (display_wayland->wl_display);
|
||||
wl_source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
|
||||
g_source_add_poll (source, &wl_source->pfd);
|
||||
|
||||
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
|
||||
g_source_set_can_recurse (source, TRUE);
|
||||
g_source_attach (source, NULL);
|
||||
|
||||
/* SOURCE 2 */
|
||||
source = g_source_new (&gdk_wayland_poll_source_funcs,
|
||||
sizeof (GdkWaylandPollSource));
|
||||
display_wayland->poll_source = source;
|
||||
poll_source = (GdkWaylandPollSource *) source;
|
||||
name = g_strdup_printf ("GDK Wayland Poll source (%s)",
|
||||
gdk_display_get_name (display));
|
||||
g_source_set_name (source, name);
|
||||
g_free (name);
|
||||
|
||||
poll_source->display = display_wayland;
|
||||
poll_source->pfd.fd = wl_display_get_fd (display_wayland->wl_display);
|
||||
poll_source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
|
||||
g_source_add_poll (source, &poll_source->pfd);
|
||||
|
||||
/* We must guarantee to ALWAYS be called and called FIRST after
|
||||
* every poll - or rather: after every prepare().
|
||||
* Any other source might call Wayland functions and in turn
|
||||
* block while waiting for us.
|
||||
* And GSource has no after_pool() vfunc, check() is not guaranteed
|
||||
* to be called.
|
||||
*/
|
||||
g_source_set_priority (source, G_MININT);
|
||||
g_source_attach (source, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_display_uninstall_gsources (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
if (display_wayland->event_source)
|
||||
{
|
||||
g_source_destroy (display_wayland->event_source);
|
||||
g_source_unref (display_wayland->event_source);
|
||||
display_wayland->event_source = NULL;
|
||||
}
|
||||
if (display_wayland->poll_source)
|
||||
{
|
||||
g_source_destroy (display_wayland->poll_source);
|
||||
g_source_unref (display_wayland->poll_source);
|
||||
display_wayland->poll_source = NULL;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_queue_events (GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWaylandPollSource *poll_source;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
GdkWaylandEventSource *source;
|
||||
GList *l;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
source = (GdkWaylandEventSource *) display_wayland->event_source;
|
||||
|
||||
if (wl_display_dispatch_pending (display_wayland->wl_display) < 0)
|
||||
{
|
||||
g_message ("Error %d (%s) dispatching to Wayland display.",
|
||||
@@ -330,6 +234,10 @@ _gdk_wayland_display_queue_events (GdkDisplay *display)
|
||||
}
|
||||
}
|
||||
|
||||
poll_source = (GdkWaylandPollSource *) display_wayland->poll_source;
|
||||
poll_source->can_dispatch = FALSE;
|
||||
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
|
||||
{
|
||||
g_message ("Lost connection to Wayland compositor.");
|
||||
_exit (1);
|
||||
}
|
||||
source->pfd.revents = 0;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,6 @@ void gdk_wayland_display_system_bell (GdkDisplay *display,
|
||||
struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
GdkCursor *cursor,
|
||||
double desired_scale,
|
||||
gboolean use_viewporter,
|
||||
guint image_index,
|
||||
int *hotspot_x,
|
||||
int *hotspot_y,
|
||||
@@ -184,8 +183,7 @@ void gdk_wayland_device_unset_touch_grab (GdkDevice *device,
|
||||
GdkEventSequence *sequence);
|
||||
|
||||
void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event);
|
||||
void gdk_wayland_display_install_gsources (GdkWaylandDisplay *display_wayland);
|
||||
void gdk_wayland_display_uninstall_gsources (GdkWaylandDisplay *display_wayland);
|
||||
GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display);
|
||||
void _gdk_wayland_display_queue_events (GdkDisplay *display);
|
||||
|
||||
GdkAppLaunchContext *_gdk_wayland_display_get_app_launch_context (GdkDisplay *display);
|
||||
|
||||
@@ -4261,7 +4261,6 @@ init_pointer_data (GdkWaylandPointerData *pointer_data,
|
||||
wl_surface_add_listener (pointer_data->pointer_surface,
|
||||
&pointer_surface_listener,
|
||||
logical_device);
|
||||
|
||||
if (display_wayland->viewporter)
|
||||
pointer_data->pointer_surface_viewport = wp_viewporter_get_viewport (display_wayland->viewporter, pointer_data->pointer_surface);
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ get_gl_texture_wl_buffer (GdkWaylandSubsurface *self,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
&gl_buffer_listener,
|
||||
g_memdup (&gldata, sizeof (gldata)));
|
||||
g_memdup2 (&gldata, sizeof (gldata)));
|
||||
}
|
||||
|
||||
static struct wl_buffer *
|
||||
|
||||
@@ -389,7 +389,7 @@ create_image_desc (GdkWaylandColor *color,
|
||||
}
|
||||
else
|
||||
{
|
||||
xx_image_description_v4_add_listener (desc, &cs_image_desc_listener, g_memdup (&data, sizeof data));
|
||||
xx_image_description_v4_add_listener (desc, &cs_image_desc_listener, g_memdup2 (&data, sizeof data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,23 +63,23 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
int scale;
|
||||
cairo_t *cr;
|
||||
int width, height;
|
||||
RECT queued_window_rect;
|
||||
RECT queued_hwnd_rect;
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
|
||||
queued_window_rect = gdk_win32_surface_handle_queued_move_resize (draw_context);
|
||||
queued_hwnd_rect = gdk_win32_surface_handle_queued_move_resize (draw_context);
|
||||
|
||||
width = queued_window_rect.right - queued_window_rect.left;
|
||||
height = queued_window_rect.bottom - queued_window_rect.top;
|
||||
width = queued_hwnd_rect.right - queued_hwnd_rect.left;
|
||||
height = queued_hwnd_rect.bottom - queued_hwnd_rect.top;
|
||||
width = MAX (width, 1);
|
||||
height = MAX (height, 1);
|
||||
|
||||
self->window_surface = create_cairo_surface_for_surface (surface, scale);
|
||||
self->hwnd_surface = create_cairo_surface_for_surface (surface, scale);
|
||||
|
||||
if (!self->double_buffered)
|
||||
/* Non-double-buffered windows paint on the window surface directly */
|
||||
self->paint_surface = cairo_surface_reference (self->window_surface);
|
||||
/* Non-double-buffered GDK surfaces paint on the window surface directly */
|
||||
self->paint_surface = cairo_surface_reference (self->hwnd_surface);
|
||||
else
|
||||
{
|
||||
if (width > self->db_width ||
|
||||
@@ -92,13 +92,13 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
self->db_surface = gdk_surface_create_similar_surface (surface,
|
||||
cairo_surface_get_content (self->window_surface),
|
||||
cairo_surface_get_content (self->hwnd_surface),
|
||||
self->db_width,
|
||||
self->db_height);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
/* Double-buffered windows paint on a DB surface.
|
||||
/* Double-buffered GDK surfaces paint on a DB surface.
|
||||
* Due to performance concerns we don't recreate it unless forced to.
|
||||
*/
|
||||
self->paint_surface = cairo_surface_reference (self->db_surface);
|
||||
@@ -128,19 +128,19 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GdkWin32CairoContext *self = GDK_WIN32_CAIRO_CONTEXT (draw_context);
|
||||
|
||||
/* The code to resize double-buffered windows immediately
|
||||
/* The code to resize double-buffered GDK surfaces immediately
|
||||
* before blitting the buffer contents onto them used
|
||||
* to be here.
|
||||
*/
|
||||
|
||||
/* For double-buffered windows we need to blit
|
||||
* the DB buffer contents into the window itself.
|
||||
/* For double-buffered GDK surfaces we need to blit
|
||||
* the DB buffer contents into the GDK surface itself.
|
||||
*/
|
||||
if (self->double_buffered)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = cairo_create (self->window_surface);
|
||||
cr = cairo_create (self->hwnd_surface);
|
||||
|
||||
cairo_set_source_surface (cr, self->paint_surface, 0, 0);
|
||||
gdk_cairo_region (cr, painted);
|
||||
@@ -152,10 +152,10 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
cairo_surface_flush (self->window_surface);
|
||||
cairo_surface_flush (self->hwnd_surface);
|
||||
|
||||
g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
g_clear_pointer (&self->hwnd_surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -39,7 +39,7 @@ struct _GdkWin32CairoContext
|
||||
GdkCairoContext parent_instance;
|
||||
|
||||
/* Set to TRUE when double-buffering is used.
|
||||
* Layered windows use their own, custom double-buffering
|
||||
* Layered HWNDs use their own, custom double-buffering
|
||||
* code that is unaffected by this flag.
|
||||
*/
|
||||
guint double_buffered : 1;
|
||||
@@ -51,11 +51,11 @@ struct _GdkWin32CairoContext
|
||||
int db_width;
|
||||
int db_height;
|
||||
|
||||
/* Surface for the window DC */
|
||||
cairo_surface_t *window_surface;
|
||||
/* Surface for the underlying window DC */
|
||||
cairo_surface_t *hwnd_surface;
|
||||
/* A reference to db_surface (when double-buffering).
|
||||
* When not using double-buffering this is a reference
|
||||
* to window_surface.
|
||||
* to hwnd_surface.
|
||||
*/
|
||||
cairo_surface_t *paint_surface;
|
||||
};
|
||||
|
||||
@@ -89,7 +89,7 @@ texts (strings) or textures (GdkPixbufs) this way.
|
||||
|
||||
On Windows:
|
||||
Clipboard is opened by OpenClipboard(), emptied by EmptyClipboard() (which also
|
||||
makes the window the clipboard owner), data is put into it by SetClipboardData().
|
||||
makes the HWND the clipboard owner), data is put into it by SetClipboardData().
|
||||
Clipboard is closed with CloseClipboard().
|
||||
If SetClipboardData() is given a NULL data value, the owner will later
|
||||
receive WM_RENDERFORMAT message, in response to which it must call
|
||||
@@ -239,7 +239,7 @@ on all the clipboards it owns. This creates multiple write stream (one for each
|
||||
format being stored), each backed by a HGLOBAL memory object. Once all memory
|
||||
objects are written, the backend queues a store operation, passing along
|
||||
all these HGLOBAL objects. The clipboard thread processes that by sending
|
||||
WM_RENDERALLFORMATS to the window, then signals the task that it's done.
|
||||
WM_RENDERALLFORMATS to the surface HWND, then signals the task that it's done.
|
||||
|
||||
When clipboard owner changes, the old owner receives WM_DESTROYCLIPBOARD message,
|
||||
the clipboard thread schedules a call to gdk_clipboard_claim_remote()
|
||||
@@ -390,10 +390,10 @@ typedef struct _GdkWin32ClipboardThread GdkWin32ClipboardThread;
|
||||
|
||||
struct _GdkWin32ClipboardThread
|
||||
{
|
||||
/* A hidden window that owns our clipboard
|
||||
/* A hidden HWND that owns our clipboard
|
||||
* and receives clipboard-related messages.
|
||||
*/
|
||||
HWND clipboard_window;
|
||||
HWND clipboard_hwnd;
|
||||
|
||||
/* We receive instructions from the main thread in this queue */
|
||||
GAsyncQueue *input_queue;
|
||||
@@ -483,11 +483,11 @@ _gdk_win32_format_uses_hdata (UINT w32format)
|
||||
|
||||
/* This function is called in the main thread */
|
||||
static gboolean
|
||||
clipboard_window_created (gpointer user_data)
|
||||
clipboard_hwnd_created (gpointer user_data)
|
||||
{
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
|
||||
clipdrop->clipboard_window = (HWND) user_data;
|
||||
clipdrop->clipboard_hwnd = (HWND) user_data;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -730,7 +730,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
error_code = try_open_clipboard (adv->unset ? NULL : clipboard_thread_data->clipboard_window);
|
||||
error_code = try_open_clipboard (adv->unset ? NULL : clipboard_thread_data->clipboard_hwnd);
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -809,7 +809,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_window);
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
|
||||
|
||||
if (error_code == ERROR_ACCESS_DENIED)
|
||||
return TRUE;
|
||||
@@ -831,7 +831,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
|
||||
* that we already own, otherwise we're just killing stuff that some other
|
||||
* process put in there, which is not nice.
|
||||
*/
|
||||
if (GetClipboardOwner () != clipboard_thread_data->clipboard_window)
|
||||
if (GetClipboardOwner () != clipboard_thread_data->clipboard_hwnd)
|
||||
{
|
||||
send_response (store->parent.item_type,
|
||||
store->parent.opaque_task,
|
||||
@@ -952,7 +952,7 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_window);
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
|
||||
else
|
||||
error_code = try_open_clipboard (clipboard_thread_data->clipboard_opened_for);
|
||||
|
||||
@@ -1119,7 +1119,7 @@ discard_render (GdkWin32ClipboardThreadRender *render,
|
||||
}
|
||||
|
||||
static LRESULT
|
||||
inner_clipboard_window_procedure (HWND hwnd,
|
||||
inner_clipboard_hwnd_procedure (HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
@@ -1139,7 +1139,7 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
|
||||
if (queue_is_empty && clipboard_thread_data->wakeup_timer)
|
||||
{
|
||||
API_CALL (KillTimer, (clipboard_thread_data->clipboard_window, clipboard_thread_data->wakeup_timer));
|
||||
API_CALL (KillTimer, (clipboard_thread_data->clipboard_hwnd, clipboard_thread_data->wakeup_timer));
|
||||
clipboard_thread_data->wakeup_timer = 0;
|
||||
}
|
||||
|
||||
@@ -1159,11 +1159,11 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
clipboard_thread_data->wakeup_timer != 0)
|
||||
return 0;
|
||||
|
||||
if (SetTimer (clipboard_thread_data->clipboard_window, 1, 1000, NULL))
|
||||
if (SetTimer (clipboard_thread_data->clipboard_hwnd, 1, 1000, NULL))
|
||||
clipboard_thread_data->wakeup_timer = 1;
|
||||
else
|
||||
g_critical ("Failed to set a timer for the clipboard window 0x%p: %lu",
|
||||
clipboard_thread_data->clipboard_window,
|
||||
g_critical ("Failed to set a timer for the clipboard HWND 0x%p: %lu",
|
||||
clipboard_thread_data->clipboard_hwnd,
|
||||
GetLastError ());
|
||||
}
|
||||
|
||||
@@ -1235,7 +1235,7 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
clipboard_thread_data->stored_hwnd_owner = hwnd_owner;
|
||||
clipboard_thread_data->owner_change_time = g_get_monotonic_time ();
|
||||
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_window)
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
|
||||
{
|
||||
if (clipboard_thread_data->cached_advertisement)
|
||||
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
|
||||
@@ -1243,9 +1243,9 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
clipboard_thread_data->cached_advertisement = NULL;
|
||||
}
|
||||
|
||||
API_CALL (PostMessage, (clipboard_thread_data->clipboard_window, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipboard_thread_data->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_window)
|
||||
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_owner_changed, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -1383,7 +1383,7 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
_clipboard_window_procedure (HWND hwnd,
|
||||
_clipboard_hwnd_procedure (HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
@@ -1392,7 +1392,7 @@ _clipboard_window_procedure (HWND hwnd,
|
||||
|
||||
GDK_NOTE (EVENTS, g_print ("clipboard thread %s %p",
|
||||
_gdk_win32_message_to_string (message), hwnd));
|
||||
retval = inner_clipboard_window_procedure (hwnd, message, wparam, lparam);
|
||||
retval = inner_clipboard_hwnd_procedure (hwnd, message, wparam, lparam);
|
||||
|
||||
GDK_NOTE (EVENTS, g_print (" => %" G_GINT64_FORMAT "\n", (gint64) retval));
|
||||
|
||||
@@ -1400,7 +1400,7 @@ _clipboard_window_procedure (HWND hwnd,
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a hidden window and add a clipboard listener
|
||||
* Creates a hidden HWND and add a clipboard listener
|
||||
*/
|
||||
static gboolean
|
||||
register_clipboard_notification ()
|
||||
@@ -1409,7 +1409,7 @@ register_clipboard_notification ()
|
||||
ATOM klass;
|
||||
|
||||
wclass.lpszClassName = L"GdkClipboardNotification";
|
||||
wclass.lpfnWndProc = _clipboard_window_procedure;
|
||||
wclass.lpfnWndProc = _clipboard_hwnd_procedure;
|
||||
wclass.hInstance = this_module ();
|
||||
wclass.cbWndExtra = sizeof (GdkWin32ClipboardThread *);
|
||||
|
||||
@@ -1417,23 +1417,23 @@ register_clipboard_notification ()
|
||||
if (!klass)
|
||||
return FALSE;
|
||||
|
||||
clipboard_thread_data->clipboard_window = CreateWindow (MAKEINTRESOURCE (klass),
|
||||
clipboard_thread_data->clipboard_hwnd = CreateWindow (MAKEINTRESOURCE (klass),
|
||||
NULL, WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL,
|
||||
this_module (), NULL);
|
||||
|
||||
if (clipboard_thread_data->clipboard_window == NULL)
|
||||
if (clipboard_thread_data->clipboard_hwnd == NULL)
|
||||
goto failed;
|
||||
|
||||
SetLastError (0);
|
||||
|
||||
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_window) == FALSE)
|
||||
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_hwnd) == FALSE)
|
||||
{
|
||||
DestroyWindow (clipboard_thread_data->clipboard_window);
|
||||
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_window_created, (gpointer) clipboard_thread_data->clipboard_window, NULL);
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) clipboard_thread_data->clipboard_hwnd, NULL);
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -1472,8 +1472,8 @@ _gdk_win32_clipboard_thread_main (gpointer data)
|
||||
}
|
||||
|
||||
/* Just in case, as this should only happen when we shut down */
|
||||
DestroyWindow (clipboard_thread_data->clipboard_window);
|
||||
CloseHandle (clipboard_thread_data->clipboard_window);
|
||||
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
|
||||
CloseHandle (clipboard_thread_data->clipboard_hwnd);
|
||||
g_async_queue_unref (queue);
|
||||
g_clear_pointer (&clipboard_thread_data, g_free);
|
||||
|
||||
@@ -2756,7 +2756,7 @@ _gdk_win32_advertise_clipboard_contentformats (GTask *task,
|
||||
gsize mime_types_len;
|
||||
gsize i;
|
||||
|
||||
g_assert (clipdrop->clipboard_window != NULL);
|
||||
g_assert (clipdrop->clipboard_hwnd != NULL);
|
||||
|
||||
adv->parent.item_type = GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE;
|
||||
adv->parent.start_time = g_get_monotonic_time ();
|
||||
@@ -2779,7 +2779,7 @@ _gdk_win32_advertise_clipboard_contentformats (GTask *task,
|
||||
}
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, adv);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_window, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -2794,7 +2794,7 @@ _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
|
||||
gsize mime_types_len;
|
||||
gsize i;
|
||||
|
||||
g_assert (clipdrop->clipboard_window != NULL);
|
||||
g_assert (clipdrop->clipboard_hwnd != NULL);
|
||||
|
||||
retr->parent.item_type = GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE;
|
||||
retr->parent.start_time = g_get_monotonic_time ();
|
||||
@@ -2809,7 +2809,7 @@ _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
|
||||
_gdk_win32_add_contentformat_to_pairs (mime_types[i], retr->pairs);
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, retr);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_window, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -2890,7 +2890,7 @@ clipboard_store_hdata_ready (GObject *clipboard,
|
||||
store->elements = prep->elements;
|
||||
|
||||
g_async_queue_push (clipdrop->clipboard_open_thread_queue, store);
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_window, thread_wakeup_message, 0, 0));
|
||||
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
|
||||
|
||||
g_free (prep);
|
||||
}
|
||||
@@ -2907,7 +2907,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
|
||||
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
|
||||
GdkWin32ClipboardStorePrep *prep;
|
||||
|
||||
g_assert (clipdrop->clipboard_window != NULL);
|
||||
g_assert (clipdrop->clipboard_hwnd != NULL);
|
||||
|
||||
mime_types = gdk_content_formats_get_mime_types (contentformats, &n_mime_types);
|
||||
|
||||
|
||||
@@ -178,12 +178,12 @@ struct _GdkWin32Clipdrop
|
||||
*/
|
||||
GAsyncQueue *clipboard_render_queue;
|
||||
|
||||
/* Window handle for the clipboard window that we
|
||||
/* Window handle for the clipboard surface that we
|
||||
* receive from the clipboard thread. We use that
|
||||
* to wake up the clipboard window main loop by
|
||||
* to wake up the clipboard surface main loop by
|
||||
* posting a message to it.
|
||||
*/
|
||||
HWND clipboard_window;
|
||||
HWND clipboard_hwnd;
|
||||
|
||||
/* The thread that calls DoDragDrop (), which would
|
||||
* normally block our main thread, as it runs its own
|
||||
|
||||
@@ -61,10 +61,10 @@ _gdk_device_virtual_set_active (GdkDevice *device,
|
||||
|
||||
static void
|
||||
gdk_device_virtual_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface *surface,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (window);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWin32HCursor *win32_hcursor = NULL;
|
||||
|
||||
if (cursor == NULL)
|
||||
@@ -74,39 +74,39 @@ gdk_device_virtual_set_surface_cursor (GdkDevice *device,
|
||||
win32_hcursor = gdk_win32_display_get_win32hcursor (GDK_WIN32_DISPLAY (display), cursor);
|
||||
|
||||
/* This is correct because the code up the stack already
|
||||
* checked that cursor is currently inside this window,
|
||||
* checked that cursor is currently inside this surface,
|
||||
* and wouldn't have called this function otherwise.
|
||||
*/
|
||||
if (win32_hcursor != NULL)
|
||||
SetCursor (gdk_win32_hcursor_get_handle (win32_hcursor));
|
||||
|
||||
g_set_object (&GDK_WIN32_SURFACE (window)->cursor, win32_hcursor);
|
||||
g_set_object (&GDK_WIN32_SURFACE (surface)->cursor, win32_hcursor);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_virtual_query_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface **child_window,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask)
|
||||
GdkSurface *surface,
|
||||
GdkSurface **child_surface,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
|
||||
|
||||
_gdk_device_win32_query_state (virtual->active_device,
|
||||
window, child_window,
|
||||
surface, child_surface,
|
||||
win_x, win_y,
|
||||
mask);
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_device_virtual_grab (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
GdkSurface *surface,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
{
|
||||
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
|
||||
{
|
||||
@@ -124,7 +124,7 @@ gdk_device_virtual_grab (GdkDevice *device,
|
||||
else
|
||||
SetCursor (LoadCursor (NULL, IDC_ARROW));
|
||||
|
||||
SetCapture (GDK_SURFACE_HWND (window));
|
||||
SetCapture (GDK_SURFACE_HWND (surface));
|
||||
}
|
||||
|
||||
return GDK_GRAB_SUCCESS;
|
||||
|
||||
@@ -49,8 +49,8 @@ void _gdk_device_virtual_set_active (GdkDevice *device,
|
||||
|
||||
void
|
||||
gdk_device_virtual_query_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface **child_window,
|
||||
GdkSurface *surface,
|
||||
GdkSurface **child_surface,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask);
|
||||
|
||||
+25
-25
@@ -32,9 +32,9 @@
|
||||
G_DEFINE_TYPE (GdkDeviceWin32, gdk_device_win32, GDK_TYPE_DEVICE)
|
||||
|
||||
static void
|
||||
gdk_device_win32_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkCursor *cursor)
|
||||
gdk_device_win32_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ get_current_mask (void)
|
||||
|
||||
static void
|
||||
gdk_device_win32_query_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface **child_window,
|
||||
GdkSurface *surface,
|
||||
GdkSurface **child_surface,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask)
|
||||
@@ -76,10 +76,10 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
HWND hwnd, hwndc;
|
||||
int scale;
|
||||
|
||||
if (window)
|
||||
if (surface)
|
||||
{
|
||||
scale = GDK_WIN32_SURFACE (window)->surface_scale;
|
||||
hwnd = GDK_SURFACE_HWND (window);
|
||||
scale = GDK_WIN32_SURFACE (surface)->surface_scale;
|
||||
hwnd = GDK_SURFACE_HWND (surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -100,14 +100,14 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
if (win_y)
|
||||
*win_y = point.y / scale;
|
||||
|
||||
if (hwnd && child_window)
|
||||
if (hwnd && child_surface)
|
||||
{
|
||||
hwndc = ChildWindowFromPoint (hwnd, point);
|
||||
|
||||
if (hwndc && hwndc != hwnd)
|
||||
*child_window = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
|
||||
else
|
||||
*child_window = NULL; /* Direct child unknown to gdk */
|
||||
*child_surface = NULL; /* Direct child unknown to gdk */
|
||||
}
|
||||
|
||||
if (mask)
|
||||
@@ -116,26 +116,26 @@ gdk_device_win32_query_state (GdkDevice *device,
|
||||
|
||||
void
|
||||
_gdk_device_win32_query_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface **child_window,
|
||||
GdkSurface *surface,
|
||||
GdkSurface **child_surface,
|
||||
double *win_x,
|
||||
double *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
if (GDK_IS_DEVICE_VIRTUAL (device))
|
||||
gdk_device_virtual_query_state (device, window, child_window, win_x, win_y, mask);
|
||||
gdk_device_virtual_query_state (device, surface, child_surface, win_x, win_y, mask);
|
||||
else if (GDK_IS_DEVICE_WINTAB (device))
|
||||
gdk_device_wintab_query_state (device, window, child_window, win_x, win_y, mask);
|
||||
gdk_device_wintab_query_state (device, surface, child_surface, win_x, win_y, mask);
|
||||
else
|
||||
gdk_device_win32_query_state (device, window, child_window, win_x, win_y, mask);
|
||||
gdk_device_win32_query_state (device, surface, child_surface, win_x, win_y, mask);
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_device_win32_grab (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface *surface,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
{
|
||||
@@ -162,7 +162,7 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
|
||||
double *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkSurface *window = NULL;
|
||||
GdkSurface *surface = NULL;
|
||||
GdkWin32Surface *impl = NULL;
|
||||
POINT screen_pt, client_pt;
|
||||
HWND hwnd;
|
||||
@@ -173,21 +173,21 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
|
||||
|
||||
/* Use WindowFromPoint instead of ChildWindowFromPoint(Ex).
|
||||
* Only WindowFromPoint is able to look through transparent
|
||||
* layered windows.
|
||||
* layered HWNDs.
|
||||
*/
|
||||
hwnd = GetAncestor (WindowFromPoint (screen_pt), GA_ROOT);
|
||||
|
||||
/* Verify that we're really inside the client area of the window */
|
||||
/* Verify that we're really inside the client area of the HWND */
|
||||
GetClientRect (hwnd, &rect);
|
||||
screen_to_client (hwnd, screen_pt, &client_pt);
|
||||
if (!PtInRect (&rect, client_pt))
|
||||
hwnd = NULL;
|
||||
|
||||
window = gdk_win32_handle_table_lookup_ (hwnd);
|
||||
surface = gdk_win32_handle_table_lookup_ (hwnd);
|
||||
|
||||
if (window && (win_x || win_y))
|
||||
if (surface && (win_x || win_y))
|
||||
{
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (win_x)
|
||||
*win_x = client_pt.x / impl->surface_scale;
|
||||
@@ -195,7 +195,7 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
|
||||
*win_y = client_pt.y / impl->surface_scale;
|
||||
}
|
||||
|
||||
return window;
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user