Merge ~3v1n0/ubuntu/+source/mutter:ubuntu/master into ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/master

Proposed by Marco Trevisan (Treviño)
Status: Merged
Merged at revision: 65552c3b33198c47443bed46946aa528ce006034
Proposed branch: ~3v1n0/ubuntu/+source/mutter:ubuntu/master
Merge into: ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/master
Diff against target: 62190 lines (+21027/-14122)
503 files modified
NEWS (+117/-4)
clutter/clutter/cally/cally-actor.c (+2/-4)
clutter/clutter/clutter-actor-meta.c (+1/-2)
clutter/clutter/clutter-actor.c (+101/-18)
clutter/clutter/clutter-backend.c (+2/-2)
clutter/clutter/clutter-binding-pool.c (+1/-2)
clutter/clutter/clutter-blur-effect.c (+4/-6)
clutter/clutter/clutter-brightness-contrast-effect.c (+1/-3)
clutter/clutter/clutter-click-action.c (+4/-0)
clutter/clutter/clutter-clone.c (+7/-0)
clutter/clutter/clutter-colorize-effect.c (+1/-3)
clutter/clutter/clutter-deform-effect.c (+1/-0)
clutter/clutter/clutter-deprecated.h (+0/-1)
clutter/clutter/clutter-desaturate-effect.c (+1/-3)
clutter/clutter/clutter-device-manager-private.h (+20/-0)
clutter/clutter/clutter-device-manager.c (+152/-0)
clutter/clutter/clutter-device-manager.h (+34/-0)
clutter/clutter/clutter-effect-private.h (+1/-1)
clutter/clutter/clutter-effect.c (+8/-7)
clutter/clutter/clutter-effect.h (+9/-9)
clutter/clutter/clutter-enum-types.h.in (+1/-1)
clutter/clutter/clutter-enums.h (+82/-26)
clutter/clutter/clutter-event.c (+3/-0)
clutter/clutter/clutter-event.h (+1/-0)
clutter/clutter/clutter-feature.c (+1/-5)
clutter/clutter/clutter-input-device.c (+8/-2)
clutter/clutter/clutter-input-pointer-a11y-private.h (+42/-0)
clutter/clutter/clutter-input-pointer-a11y.c (+669/-0)
clutter/clutter/clutter-main.c (+80/-592)
clutter/clutter/clutter-main.h (+0/-3)
clutter/clutter/clutter-marshal.list (+1/-0)
clutter/clutter/clutter-master-clock-default.c (+4/-92)
clutter/clutter/clutter-paint-nodes.c (+1/-2)
clutter/clutter/clutter-path.c (+2/-4)
clutter/clutter/clutter-private.h (+5/-8)
clutter/clutter/clutter-script-parser.c (+40/-71)
clutter/clutter/clutter-script.c (+5/-11)
clutter/clutter/clutter-stage-manager.c (+2/-2)
clutter/clutter/clutter-stage-private.h (+1/-1)
clutter/clutter/clutter-stage-view-private.h (+37/-0)
clutter/clutter/clutter-stage-view.c (+17/-0)
clutter/clutter/clutter-stage-view.h (+4/-13)
clutter/clutter/clutter-stage-window.c (+0/-18)
clutter/clutter/clutter-stage-window.h (+0/-8)
clutter/clutter/clutter-stage.c (+196/-448)
clutter/clutter/clutter-stage.h (+9/-15)
clutter/clutter/clutter-text-buffer.c (+7/-7)
clutter/clutter/clutter-text.c (+5/-5)
clutter/clutter/clutter-util.c (+54/-8)
clutter/clutter/clutter.h (+1/-0)
clutter/clutter/cogl/clutter-stage-cogl.c (+79/-31)
clutter/clutter/cogl/clutter-stage-cogl.h (+3/-0)
clutter/clutter/deprecated/clutter-texture.c (+1/-3)
clutter/clutter/evdev/clutter-input-device-evdev.c (+49/-37)
clutter/clutter/evdev/clutter-input-device-evdev.h (+1/-1)
clutter/clutter/evdev/clutter-seat-evdev.c (+1/-0)
clutter/clutter/meson.build (+11/-10)
clutter/clutter/x11/clutter-backend-x11.c (+8/-11)
clutter/clutter/x11/clutter-backend-x11.h (+0/-1)
clutter/clutter/x11/clutter-device-manager-xi2.c (+77/-1)
clutter/clutter/x11/clutter-input-device-xi2.c (+77/-0)
clutter/clutter/x11/clutter-input-device-xi2.h (+3/-0)
clutter/clutter/x11/clutter-keymap-x11.c (+2/-1)
clutter/clutter/x11/clutter-stage-x11.c (+7/-297)
clutter/clutter/x11/clutter-stage-x11.h (+0/-2)
clutter/meson.build (+8/-9)
clutter/tests/conform/actor-destroy.c (+3/-3)
clutter/tests/conform/actor-shader-effect.c (+18/-14)
clutter/tests/conform/meson.build (+4/-6)
clutter/tests/conform/timeline-interpolate.c (+5/-6)
clutter/tests/conform/timeline.c (+1/-2)
clutter/tests/interactive/meson.build (+1/-4)
clutter/tests/interactive/test-actors.c (+0/-1)
clutter/tests/interactive/test-bind-constraint.c (+0/-1)
clutter/tests/interactive/test-cairo-clock.c (+0/-1)
clutter/tests/interactive/test-cogl-offscreen.c (+2/-2)
clutter/tests/interactive/test-cogl-tex-convert.c (+2/-2)
clutter/tests/interactive/test-cogl-tex-polygon.c (+2/-2)
clutter/tests/interactive/test-cogl-tex-tile.c (+2/-2)
clutter/tests/interactive/test-content.c (+0/-1)
clutter/tests/interactive/test-events.c (+1/-40)
clutter/tests/interactive/test-grab.c (+0/-4)
clutter/tests/interactive/test-image.c (+0/-1)
clutter/tests/interactive/test-rotate-zoom.c (+0/-1)
clutter/tests/interactive/test-stage-sizing.c (+0/-59)
clutter/tests/interactive/test-state-script.c (+0/-1)
clutter/tests/interactive/test-table-layout.c (+0/-1)
clutter/tests/interactive/test-texture-async.c (+0/-2)
clutter/tests/interactive/test-touch-events.c (+0/-1)
clutter/tests/performance/meson.build (+1/-1)
cogl/cogl-config.h.meson (+3/-0)
cogl/cogl-pango/cogl-pango-display-list.c (+2/-2)
cogl/cogl-pango/cogl-pango-fontmap.c (+2/-2)
cogl/cogl-pango/cogl-pango-glyph-cache.c (+2/-2)
cogl/cogl-pango/cogl-pango-render.c (+13/-6)
cogl/cogl-path/cogl-path-enum-types.h.in (+1/-1)
cogl/cogl-path/cogl-path.c (+26/-26)
cogl/cogl/cogl-atlas-texture.c (+29/-37)
cogl/cogl/cogl-atlas-texture.h (+4/-4)
cogl/cogl/cogl-atlas.c (+18/-26)
cogl/cogl/cogl-attribute-buffer.c (+1/-1)
cogl/cogl/cogl-attribute.c (+10/-10)
cogl/cogl/cogl-bitmap-conversion.c (+8/-8)
cogl/cogl/cogl-bitmap-pixbuf.c (+3/-4)
cogl/cogl/cogl-bitmap-private.h (+21/-21)
cogl/cogl/cogl-bitmap.c (+21/-23)
cogl/cogl/cogl-bitmap.h (+4/-3)
cogl/cogl/cogl-blend-string.c (+30/-38)
cogl/cogl/cogl-blend-string.h (+1/-1)
cogl/cogl/cogl-blit.c (+23/-20)
cogl/cogl/cogl-buffer-private.h (+4/-4)
cogl/cogl/cogl-buffer.c (+23/-25)
cogl/cogl/cogl-buffer.h (+2/-3)
cogl/cogl/cogl-clip-stack.c (+1/-1)
cogl/cogl/cogl-color.c (+5/-5)
cogl/cogl/cogl-context-private.h (+1/-11)
cogl/cogl/cogl-context.c (+4/-94)
cogl/cogl/cogl-context.h (+2/-28)
cogl/cogl/cogl-debug-options.h (+0/-11)
cogl/cogl/cogl-debug.c (+0/-2)
cogl/cogl/cogl-debug.h (+0/-2)
cogl/cogl/cogl-depth-state.c (+8/-8)
cogl/cogl/cogl-display.c (+4/-4)
cogl/cogl/cogl-display.h (+2/-2)
cogl/cogl/cogl-driver.h (+7/-7)
cogl/cogl/cogl-euler.c (+2/-2)
cogl/cogl/cogl-framebuffer-private.h (+9/-68)
cogl/cogl/cogl-framebuffer.c (+110/-190)
cogl/cogl/cogl-framebuffer.h (+78/-63)
cogl/cogl/cogl-gles2-context.c (+29/-30)
cogl/cogl/cogl-gles2.h (+6/-7)
cogl/cogl/cogl-glsl-shader.c (+3/-12)
cogl/cogl/cogl-indices.c (+9/-9)
cogl/cogl/cogl-journal.c (+2/-2)
cogl/cogl/cogl-matrix-stack.c (+2/-2)
cogl/cogl/cogl-matrix.c (+6/-6)
cogl/cogl/cogl-meta-texture.c (+13/-72)
cogl/cogl/cogl-meta-texture.h (+6/-8)
cogl/cogl/cogl-mutter.h (+1/-2)
cogl/cogl/cogl-node.c (+1/-1)
cogl/cogl/cogl-object.c (+4/-4)
cogl/cogl/cogl-offscreen.h (+5/-5)
cogl/cogl/cogl-onscreen.c (+10/-10)
cogl/cogl/cogl-pipeline-layer-private.h (+0/-11)
cogl/cogl/cogl-pipeline-layer-state-private.h (+0/-10)
cogl/cogl/cogl-pipeline-layer-state.c (+36/-195)
cogl/cogl/cogl-pipeline-layer-state.h (+6/-11)
cogl/cogl/cogl-pipeline-layer.c (+2/-18)
cogl/cogl/cogl-pipeline-private.h (+0/-11)
cogl/cogl/cogl-pipeline-state.c (+47/-110)
cogl/cogl/cogl-pipeline-state.h (+7/-43)
cogl/cogl/cogl-pipeline.c (+19/-70)
cogl/cogl/cogl-pixel-buffer.c (+4/-4)
cogl/cogl/cogl-pixel-format.c (+310/-0)
cogl/cogl/cogl-pixel-format.h (+300/-0)
cogl/cogl/cogl-poll.c (+5/-5)
cogl/cogl/cogl-primitive-texture.c (+1/-1)
cogl/cogl/cogl-primitive-texture.h (+5/-6)
cogl/cogl/cogl-primitive.c (+13/-13)
cogl/cogl/cogl-primitive.h (+2/-2)
cogl/cogl/cogl-primitives.c (+1/-5)
cogl/cogl/cogl-private.h (+1/-52)
cogl/cogl/cogl-quaternion.c (+5/-5)
cogl/cogl/cogl-rectangle-map.c (+1/-1)
cogl/cogl/cogl-renderer.c (+42/-52)
cogl/cogl/cogl-renderer.h (+4/-5)
cogl/cogl/cogl-snippet.c (+9/-9)
cogl/cogl/cogl-spans.c (+2/-2)
cogl/cogl/cogl-sub-texture.c (+25/-71)
cogl/cogl/cogl-texture-2d-private.h (+1/-0)
cogl/cogl/cogl-texture-2d-sliced.c (+36/-118)
cogl/cogl/cogl-texture-2d-sliced.h (+4/-4)
cogl/cogl/cogl-texture-2d.c (+20/-209)
cogl/cogl/cogl-texture-2d.h (+13/-31)
cogl/cogl/cogl-texture-driver.h (+2/-31)
cogl/cogl/cogl-texture-private.h (+5/-18)
cogl/cogl/cogl-texture.c (+30/-58)
cogl/cogl/cogl-texture.h (+6/-24)
cogl/cogl/cogl-trace.c (+258/-0)
cogl/cogl/cogl-trace.h (+147/-0)
cogl/cogl/cogl-types.h (+2/-223)
cogl/cogl/cogl-util.h (+1/-14)
cogl/cogl/cogl-vector.c (+6/-6)
cogl/cogl/cogl-wayland-server.h (+0/-75)
cogl/cogl/cogl-xlib-renderer-private.h (+1/-1)
cogl/cogl/cogl-xlib-renderer.c (+12/-25)
cogl/cogl/cogl.c (+8/-60)
cogl/cogl/cogl.h (+1/-4)
cogl/cogl/cogl.symbols (+0/-19)
cogl/cogl/deprecated/cogl-auto-texture.c (+33/-127)
cogl/cogl/deprecated/cogl-auto-texture.h (+2/-40)
cogl/cogl/deprecated/cogl-clutter.c (+2/-2)
cogl/cogl/deprecated/cogl-framebuffer-deprecated.c (+9/-9)
cogl/cogl/deprecated/cogl-material-compat.c (+4/-4)
cogl/cogl/deprecated/cogl-material-compat.h (+8/-13)
cogl/cogl/deprecated/cogl-program.c (+8/-10)
cogl/cogl/deprecated/cogl-shader.h (+0/-5)
cogl/cogl/deprecated/cogl-vertex-buffer.c (+1/-1)
cogl/cogl/driver/gl/cogl-attribute-gl.c (+6/-7)
cogl/cogl/driver/gl/cogl-buffer-gl-private.h (+3/-3)
cogl/cogl/driver/gl/cogl-buffer-gl.c (+18/-19)
cogl/cogl/driver/gl/cogl-clip-stack-gl.c (+2/-34)
cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h (+2/-2)
cogl/cogl/driver/gl/cogl-framebuffer-gl.c (+14/-49)
cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c (+6/-23)
cogl/cogl/driver/gl/cogl-pipeline-opengl.c (+8/-45)
cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c (+3/-6)
cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c (+1/-7)
cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h (+4/-4)
cogl/cogl/driver/gl/cogl-texture-2d-gl.c (+62/-68)
cogl/cogl/driver/gl/cogl-texture-gl.c (+1/-2)
cogl/cogl/driver/gl/cogl-util-gl-private.h (+1/-6)
cogl/cogl/driver/gl/cogl-util-gl.c (+4/-48)
cogl/cogl/driver/gl/gl/cogl-driver-gl.c (+29/-148)
cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c (+6/-98)
cogl/cogl/driver/gl/gles/cogl-driver-gles.c (+12/-39)
cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c (+8/-176)
cogl/cogl/driver/nop/cogl-driver-nop.c (+1/-2)
cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h (+2/-2)
cogl/cogl/driver/nop/cogl-framebuffer-nop.c (+2/-2)
cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h (+2/-2)
cogl/cogl/driver/nop/cogl-texture-2d-nop.c (+2/-3)
cogl/cogl/gl-prototypes/cogl-all-functions.h (+3/-23)
cogl/cogl/libmutter-cogl.map.in (+1/-3)
cogl/cogl/meson.build (+15/-12)
cogl/cogl/winsys/cogl-texture-pixmap-x11.c (+41/-122)
cogl/cogl/winsys/cogl-texture-pixmap-x11.h (+5/-5)
cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h (+6/-0)
cogl/cogl/winsys/cogl-winsys-egl-private.h (+8/-7)
cogl/cogl/winsys/cogl-winsys-egl-x11.c (+14/-14)
cogl/cogl/winsys/cogl-winsys-egl.c (+66/-41)
cogl/cogl/winsys/cogl-winsys-glx.c (+69/-157)
cogl/cogl/winsys/cogl-winsys-private.h (+6/-13)
cogl/cogl/winsys/cogl-winsys-stub.c (+4/-4)
cogl/meson.build (+14/-12)
cogl/test-fixtures/test-utils.c (+23/-67)
cogl/test-fixtures/test-utils.h (+1/-2)
cogl/tests/conform/meson.build (+27/-14)
cogl/tests/conform/meson/find-conform-unit-tests.sh (+0/-2)
cogl/tests/conform/test-blend-strings.c (+2/-2)
cogl/tests/conform/test-conform-main.c (+0/-6)
cogl/tests/conform/test-declarations.h (+0/-3)
cogl/tests/conform/test-gles2-context.c (+6/-6)
cogl/tests/conform/test-just-vertex-shader.c (+2/-2)
cogl/tests/conform/test-multitexture.c (+1/-1)
cogl/tests/conform/test-npot-texture.c (+2/-12)
cogl/tests/conform/test-pipeline-user-matrix.c (+1/-1)
cogl/tests/conform/test-point-sprite.c (+1/-1)
cogl/tests/conform/test-texture-no-allocate.c (+1/-19)
cogl/tests/meson.build (+2/-10)
cogl/tests/run-tests.sh (+28/-29)
cogl/tests/unit/meson.build (+17/-15)
cogl/tests/unit/meson/find-unit-tests.sh (+5/-2)
config.h.meson (+6/-2)
data/meson.build (+1/-1)
data/org.gnome.mutter.gschema.xml.in (+14/-0)
data/org.gnome.mutter.wayland.gschema.xml.in (+10/-3)
debian/changelog (+81/-0)
debian/control (+13/-11)
debian/control.in (+13/-11)
debian/gir1.2-mutter-5.install (+1/-0)
debian/libmutter-5-0.bug-control (+1/-0)
debian/libmutter-5-0.install (+2/-0)
debian/libmutter-5-0.lintian-overrides (+1/-1)
debian/libmutter-5-0.symbols (+70/-84)
debian/libmutter-5-dev.install (+2/-2)
debian/mutter.install (+1/-1)
debian/patches/debian/synaptics-support.patch (+4/-4)
debian/patches/meson-add-back-default_driver-option.patch (+10/-10)
debian/patches/series (+1/-4)
debian/patches/theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch (+2/-2)
debian/patches/theme-use-gtk_render_icon_suface-to-paint-button-icon.patch (+2/-2)
debian/patches/x11-Add-support-for-fractional-scaling-using-Randr.patch (+182/-186)
debian/rules (+2/-1)
dev/null (+0/-61)
meson.build (+92/-58)
meson_options.txt (+13/-1)
po/POTFILES.in (+3/-0)
po/es.po (+72/-37)
po/eu.po (+198/-1310)
po/fur.po (+77/-46)
po/hr.po (+77/-48)
po/hu.po (+45/-32)
po/id.po (+77/-45)
po/nl.po (+72/-39)
po/pt_BR.po (+96/-52)
po/ro.po (+78/-48)
src/backends/meta-backend-private.h (+7/-0)
src/backends/meta-backend.c (+71/-0)
src/backends/meta-barrier.c (+1/-1)
src/backends/meta-cursor-renderer.c (+34/-3)
src/backends/meta-cursor-sprite-xcursor.c (+2/-2)
src/backends/meta-cursor-tracker.c (+29/-1)
src/backends/meta-dnd-private.h (+2/-0)
src/backends/meta-egl.c (+93/-1)
src/backends/meta-egl.h (+13/-0)
src/backends/meta-gpu.c (+15/-14)
src/backends/meta-gpu.h (+1/-1)
src/backends/meta-input-mapper.c (+3/-12)
src/backends/meta-input-settings-private.h (+3/-0)
src/backends/meta-input-settings.c (+165/-24)
src/backends/meta-logical-monitor.c (+1/-0)
src/backends/meta-logical-monitor.h (+1/-0)
src/backends/meta-monitor-manager-dummy.c (+51/-38)
src/backends/meta-monitor-manager-private.h (+4/-8)
src/backends/meta-monitor-manager.c (+38/-126)
src/backends/meta-monitor-transform.h (+1/-0)
src/backends/meta-monitor.c (+124/-19)
src/backends/meta-monitor.h (+8/-4)
src/backends/meta-profiler.c (+206/-0)
src/backends/meta-profiler.h (+41/-0)
src/backends/meta-remote-desktop-session.c (+0/-1)
src/backends/meta-screen-cast-monitor-stream-src.c (+44/-21)
src/backends/meta-screen-cast-monitor-stream.c (+3/-1)
src/backends/meta-settings-private.h (+3/-1)
src/backends/meta-settings.c (+5/-1)
src/backends/meta-stage-private.h (+22/-0)
src/backends/meta-stage.c (+103/-1)
src/backends/native/meta-backend-native-types.h (+26/-0)
src/backends/native/meta-backend-native.c (+202/-35)
src/backends/native/meta-backend-native.h (+6/-0)
src/backends/native/meta-crtc-kms.c (+158/-384)
src/backends/native/meta-crtc-kms.h (+24/-13)
src/backends/native/meta-cursor-renderer-native.c (+15/-7)
src/backends/native/meta-drm-buffer-dumb.c (+65/-0)
src/backends/native/meta-drm-buffer-dumb.h (+35/-0)
src/backends/native/meta-drm-buffer-gbm.c (+232/-0)
src/backends/native/meta-drm-buffer-gbm.h (+43/-0)
src/backends/native/meta-drm-buffer.c (+45/-0)
src/backends/native/meta-drm-buffer.h (+46/-0)
src/backends/native/meta-gpu-kms.c (+95/-505)
src/backends/native/meta-gpu-kms.h (+10/-41)
src/backends/native/meta-kms-connector-private.h (+32/-0)
src/backends/native/meta-kms-connector.c (+607/-0)
src/backends/native/meta-kms-connector.h (+89/-0)
src/backends/native/meta-kms-crtc-private.h (+33/-0)
src/backends/native/meta-kms-crtc.c (+178/-0)
src/backends/native/meta-kms-crtc.h (+69/-0)
src/backends/native/meta-kms-device-private.h (+27/-0)
src/backends/native/meta-kms-device.c (+279/-0)
src/backends/native/meta-kms-device.h (+53/-0)
src/backends/native/meta-kms-impl-device.c (+411/-0)
src/backends/native/meta-kms-impl-device.h (+65/-0)
src/backends/native/meta-kms-impl-simple.c (+862/-0)
src/backends/native/meta-kms-impl-simple.h (+32/-0)
src/backends/native/meta-kms-impl.c (+132/-0)
src/backends/native/meta-kms-impl.h (+54/-0)
src/backends/native/meta-kms-page-flip-private.h (+57/-0)
src/backends/native/meta-kms-page-flip.c (+196/-0)
src/backends/native/meta-kms-plane.c (+409/-0)
src/backends/native/meta-kms-plane.h (+70/-0)
src/backends/native/meta-kms-private.h (+63/-0)
src/backends/native/meta-kms-types.h (+59/-0)
src/backends/native/meta-kms-update-private.h (+112/-0)
src/backends/native/meta-kms-update.c (+304/-0)
src/backends/native/meta-kms-update.h (+92/-0)
src/backends/native/meta-kms-utils.c (+83/-0)
src/backends/native/meta-kms-utils.h (+37/-0)
src/backends/native/meta-kms.c (+565/-0)
src/backends/native/meta-kms.h (+50/-0)
src/backends/native/meta-launcher.c (+5/-3)
src/backends/native/meta-monitor-manager-kms.c (+127/-251)
src/backends/native/meta-output-kms.c (+98/-449)
src/backends/native/meta-output-kms.h (+9/-5)
src/backends/native/meta-renderer-native-gles3.c (+21/-104)
src/backends/native/meta-renderer-native.c (+623/-860)
src/backends/native/meta-renderer-native.h (+2/-2)
src/backends/native/meta-udev.c (+226/-0)
src/backends/native/meta-udev.h (+43/-0)
src/backends/x11/cm/meta-backend-x11-cm.c (+11/-0)
src/backends/x11/meta-backend-x11.c (+7/-2)
src/backends/x11/meta-crtc-xrandr.c (+4/-1)
src/backends/x11/meta-gpu-xrandr.c (+7/-3)
src/backends/x11/meta-gpu-xrandr.h (+2/-2)
src/backends/x11/meta-monitor-manager-xrandr.c (+22/-20)
src/backends/x11/meta-output-xrandr.c (+7/-2)
src/backends/x11/nested/meta-backend-x11-nested.c (+38/-2)
src/backends/x11/nested/meta-backend-x11-nested.h (+2/-0)
src/backends/x11/nested/meta-renderer-x11-nested.c (+1/-1)
src/compositor/cogl-utils.c (+4/-33)
src/compositor/compositor-private.h (+5/-1)
src/compositor/compositor.c (+53/-52)
src/compositor/meta-background-actor.c (+48/-16)
src/compositor/meta-background-group.c (+0/-5)
src/compositor/meta-background-image.c (+2/-2)
src/compositor/meta-background.c (+42/-16)
src/compositor/meta-dnd.c (+30/-0)
src/compositor/meta-module.c (+1/-4)
src/compositor/meta-plugin-manager.c (+10/-0)
src/compositor/meta-plugin-manager.h (+2/-0)
src/compositor/meta-shadow-factory.c (+5/-2)
src/compositor/meta-shaped-texture.c (+57/-54)
src/compositor/meta-surface-actor-x11.c (+2/-2)
src/compositor/meta-texture-tower.c (+5/-25)
src/compositor/meta-window-actor-private.h (+17/-5)
src/compositor/meta-window-actor-wayland.c (+0/-11)
src/compositor/meta-window-actor-x11.c (+21/-22)
src/compositor/meta-window-actor.c (+135/-79)
src/compositor/plugins/default.c (+1/-4)
src/core/boxes.c (+11/-42)
src/core/display-private.h (+13/-22)
src/core/display.c (+153/-97)
src/core/edge-resistance.c (+1/-7)
src/core/events.c (+5/-3)
src/core/frame.c (+18/-12)
src/core/keybindings-private.h (+5/-0)
src/core/keybindings.c (+144/-50)
src/core/main-private.h (+8/-1)
src/core/main.c (+17/-21)
src/core/meta-clipboard-manager.c (+167/-0)
src/core/meta-clipboard-manager.h (+30/-0)
src/core/meta-launch-context.c (+1/-1)
src/core/meta-selection-source-memory.c (+125/-0)
src/core/meta-selection-source.c (+166/-0)
src/core/meta-selection.c (+347/-0)
src/core/meta-workspace-manager.c (+110/-2)
src/core/place.c (+3/-6)
src/core/prefs.c (+76/-1)
src/core/stack-tracker.c (+43/-0)
src/core/stack.c (+152/-290)
src/core/stack.h (+46/-73)
src/core/startup-notification.c (+1/-2)
src/core/util.c (+0/-14)
src/core/window-private.h (+8/-3)
src/core/window.c (+41/-103)
src/core/workspace.c (+9/-18)
src/meson.build (+84/-14)
src/meta-marshal.list (+1/-1)
src/meta/compositor-mutter.h (+0/-3)
src/meta/compositor.h (+0/-4)
src/meta/display.h (+12/-0)
src/meta/meson.build (+3/-0)
src/meta/meta-background-group.h (+9/-4)
src/meta/meta-cursor-tracker.h (+3/-0)
src/meta/meta-enum-types.h.in (+1/-1)
src/meta/meta-plugin.h (+10/-0)
src/meta/meta-selection-source-memory.h (+39/-0)
src/meta/meta-selection-source.h (+85/-0)
src/meta/meta-selection.h (+70/-0)
src/meta/meta-workspace-manager.h (+5/-0)
src/meta/meta-x11-display.h (+0/-23)
src/meta/prefs.h (+6/-0)
src/meta/types.h (+1/-0)
src/meta/util.h (+0/-3)
src/org.gnome.Mutter.RemoteDesktop.xml (+2/-1)
src/tests/README (+2/-3)
src/tests/boxes-tests.c (+1/-7)
src/tests/headless-start-test.c (+1/-1)
src/tests/meson.build (+39/-27)
src/tests/meta-backend-test.c (+24/-0)
src/tests/meta-backend-test.h (+2/-0)
src/tests/meta-gpu-test.c (+55/-0)
src/tests/meta-gpu-test.h (+7/-17)
src/tests/meta-monitor-manager-test.c (+13/-59)
src/tests/meta-monitor-manager-test.h (+1/-5)
src/tests/monitor-unit-tests.c (+12/-15)
src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest (+1/-1)
src/tests/test-utils.c (+1/-1)
src/ui/theme.c (+2/-6)
src/wayland/meta-selection-source-wayland-private.h (+46/-0)
src/wayland/meta-selection-source-wayland.c (+162/-0)
src/wayland/meta-wayland-actor-surface.c (+0/-7)
src/wayland/meta-wayland-buffer.c (+3/-0)
src/wayland/meta-wayland-cursor-surface.c (+3/-0)
src/wayland/meta-wayland-data-device.c (+326/-93)
src/wayland/meta-wayland-data-device.h (+5/-0)
src/wayland/meta-wayland-dma-buf.c (+23/-70)
src/wayland/meta-wayland-dnd-surface.c (+4/-0)
src/wayland/meta-wayland-gtk-shell.c (+4/-0)
src/wayland/meta-wayland-keyboard.c (+0/-141)
src/wayland/meta-wayland-keyboard.h (+0/-1)
src/wayland/meta-wayland-outputs.c (+21/-0)
src/wayland/meta-wayland-pointer-constraints.c (+17/-1)
src/wayland/meta-wayland-pointer.c (+24/-1)
src/wayland/meta-wayland-private.h (+7/-2)
src/wayland/meta-wayland-shell-surface.c (+20/-0)
src/wayland/meta-wayland-subsurface.c (+4/-1)
src/wayland/meta-wayland-surface.c (+11/-5)
src/wayland/meta-wayland-tablet-tool.c (+14/-3)
src/wayland/meta-wayland-versions.h (+1/-1)
src/wayland/meta-wayland.c (+14/-6)
src/wayland/meta-wayland.h (+8/-15)
src/wayland/meta-window-wayland.c (+35/-27)
src/wayland/meta-xwayland-dnd.c (+182/-1031)
src/wayland/meta-xwayland-grab-keyboard.c (+18/-4)
src/wayland/meta-xwayland-private.h (+6/-6)
src/wayland/meta-xwayland.c (+298/-51)
src/x11/events.c (+53/-25)
src/x11/iconcache.c (+1/-0)
src/x11/meta-selection-source-x11-private.h (+44/-0)
src/x11/meta-selection-source-x11.c (+252/-0)
src/x11/meta-x11-display-private.h (+41/-0)
src/x11/meta-x11-display.c (+125/-91)
src/x11/meta-x11-selection-input-stream-private.h (+54/-0)
src/x11/meta-x11-selection-input-stream.c (+557/-0)
src/x11/meta-x11-selection-output-stream-private.h (+47/-0)
src/x11/meta-x11-selection-output-stream.c (+606/-0)
src/x11/meta-x11-selection-private.h (+34/-0)
src/x11/meta-x11-selection.c (+411/-0)
src/x11/meta-x11-stack-private.h (+33/-0)
src/x11/meta-x11-stack.c (+413/-0)
src/x11/window-props.c (+1/-1)
src/x11/window-x11.c (+45/-19)
Reviewer Review Type Date Requested Status
Ubuntu Desktop Pending
Review via email: mp+371250@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/NEWS b/NEWS
2index fcdc3cf..d5640ae 100644
3--- a/NEWS
4+++ b/NEWS
5@@ -1,13 +1,126 @@
6-3.32.2
7+3.33.90
8+=======
9+* Fix visibility of clones with hidden source [Florian; #683]
10+* Reduce freezes when opening some popup windows [Carlos; #556]
11+* Be more thorough when excluding obscured areas from painting [Carlos; !698]
12+* Make it possible to start Xwayland on demand [Carlos; !709]
13+* clutter: Expose layout_manager to transitions [Florian; !716]
14+* Misc. bug fixes and cleanups [Mark, Florian, Iain, Niels, Carlos, Ray; !671,
15+ !691, !694, !696, !703, !707, !697, !710, !708, !714, #719, !721]
16+
17+Contributors:
18+ Mark Blakeney, Carlos Garnacho, Niels De Graef, Iain Lane, Florian Müllner,
19+ Ray Strode
20+
21+Translators:
22+ Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR], Fabio Tomat [fur],
23+ Florentina Mușat [ro]
24+
25+3.33.4
26+======
27+* Discard page flip retries on hotplug [Jonas; !630]
28+* Add xdg-output v2 support [Olivier; #645]
29+* Restore DRM format fallbacks [Jonas; !662]
30+* Don't emit ::size-changed when only position changed [Daniel; !568]
31+* Expose workspace layout properties [Florian; !618]
32+* Don't use grab modifiers when shortcuts are inhibited [Olivier; #642]
33+* Fix stuttering due to unchanged power save mode notifications [Georges; !674]
34+* Add API to reorder workspaces [Adam; !670]
35+* Make picking a new focus window more reliable [Marco; !669]
36+* Defer actor allocation till shown [Carlos; !677]
37+* Try to use primary GPU for copy instead of glReadPixels [Pekka; !615]
38+* Unset pointer focus when the cursor is hidden [Jonas D.; !448]
39+* Fix modifier-drag on wayland subsurfaces [Robert; !604]
40+* Fix background corruption on Nvidia after resuming from suspend [Daniel; !600]
41+* Only grab the locate-pointer key when necessary [Olivier; !685, #647]
42+* Misc. bug fixes and cleanups [Florian, Jonas, Daniel, Robert, Olivier,
43+ Georges, Marco, Carlos, Emmanuele; !648, !650, !647, !656, !658, !637,
44+ !663, !660, !659, !665, !666, !668, !667, #667, !676, !678, #672, !680,
45+ !683, !688, !689, !687]
46+
47+Contributors:
48+ Jonas Ådahl, Emmanuele Bassi, Adam Bieńkowski, Piotr Drąg, Jonas Dreßler,
49+ Olivier Fourdan, Carlos Garnacho, Robert Mader, Florian Müllner,
50+ Georges Basile Stavracas Neto, Pekka Paalanen, Marco Trevisan (Treviño),
51+ Daniel van Vugt
52+
53+Translators:
54+ Fabio Tomat [fur], Kukuh Syafaat [id]
55+
56+3.33.3
57+======
58+* Prepare for running Xwayland on demand [Carlos; !420]
59+* Fix text selection color rendering [Florian; #494]
60+* Fix black shadows when using fractional scaling [Robert; #609]
61+* Honor startup sequence workspace on wayland [Carlos; gnome-shell#674]
62+* Only emit 'grab-op-end` signal after dropping grabs [Marco; !596]
63+* Add a Sysprof-based profiler [Jonas, Georges; !197, !603]
64+* Relax "xwayland-allow-grabs" setting [Olivier; #597]
65+* Implement locate-pointer accessibility feature [Olivier; !453]
66+* Implement mouse accessibility [Olivier; !512]
67+* Consolidate frame throttling [Daniel, Georges; !363]
68+* Fix setting blank cursor under wayland [Jonas; #630]
69+* Pixel-align OpenGL cursors [Jonas; !610]
70+* Handle returning from fullscreen/maximization better [Jonas; !621]
71+* Improve screencast support on multi-monitor systems [Georges; !623]
72+* Fix running X11 applications with sudo under wayland [Hans; #643]
73+* Implement toggle-keys notification [Olivier; #637]
74+* Add initial KMS transactional support [Jonas; !525]
75+* Improve finding new focus window when the old one is closed [Marco; #308]
76+* Misc. bug fixes and cleanups [Jonas, Carlos, Marco, Florian, Pekka, Robert,
77+ Douglas, Georges, Daniel, Emil, Niels, Hans, Olivier, Ting-Wei, Corentin;
78+ !591, #398, !592, !581, !597, !598, !593, !497, #591, !545, gtk#1675, !601,
79+ #568, !564, !605, !609, !115, !214, !611, !617, !616, !619, !624, !622, !627,
80+ !628, !629, !632, !633, !631, !636, !639, !638, !634, !640, !529, !644, !590]
81+
82+Contributors:
83+ Jonas Ådahl, Piotr Drąg, Olivier Fourdan, Carlos Garnacho, Hans de Goede,
84+ Niels De Graef, Ting-Wei Lan, Robert Mader, Florian Müllner,
85+ Georges Basile Stavracas Neto, Corentin Noël, Pekka Paalanen, Douglas R. Reno,
86+ Marco Trevisan (Treviño), Emil Velikov, Daniel van Vugt
87+
88+Translators:
89+ Balázs Úr [hu], Daniel Mustieles [es], Nathan Follens [nl], Goran Vidović [hr]
90+
91+3.33.2
92+======
93+* Fix rendering lag on Xorg [Daniel; !520, !281]
94+* Misc. bug fixes and cleanups [Carlos, Marco, Jonas D., Florian, Niels,
95+ Daniel, Benjamin, Jonas Å., Ignacio, Vasilis; #598, !576, !547, !578,
96+ !583, !582, !469, !524, !119, !571, !584, !585, !586, #425]
97+
98+Contributors:
99+ Jonas Ådahl, Benjamin Berg, Jonas Dreßler, Carlos Garnacho, Niels De Graef,
100+ Vasilis Liaskovitis, Florian Müllner, Ignacio Casal Quinteiro,
101+ Marco Trevisan (Treviño), Daniel van Vugt
102+
103+Translators:
104+ Daniel Mustieles [es]
105+
106+3.33.1
107 ======
108+* Remove unused APIs and outdated driver support
109+ [Adam; !481, !468, !489, !487, !546]
110+* Enable EGL_IMG_context_priority [Adam; !454]
111 * Disable mouse keys with Numlock on [Olivier; #530]
112 * Fix crash when restarting on X11 [Marco; #576]
113+* Implement clipboard manager [Carlos; !320]
114+* Fix spurious idle signals that prevent session unblank [Jonas Å.; !543]
115 * Fix mapping of touchscreens that don't report dimensions [Carlos; #581]
116-* Fix spurious idle signals that prevent session unblank [Jonas; !543]
117-* Misc. bug fixes and cleanups [Olivier, Marco, Carlos; !552, !557, #586]
118+* Fix propagating fractional scaling factor [Robert; !537]
119+* Add experimental RT scheduling support [Carlos; !460]
120+* Misc. bug fixes and cleanups [Robert, Carlos, Olivier, Ray, Marco, Jonas D.,
121+ Georges, Daniel V., Daniel M; !467, !504, !551, !552, #575, #556, !557, !442,
122+ !562, !535, !548, #586, !567, !396, !422, !507]
123
124 Contributors:
125- Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Marco Trevisan (Treviño)
126+ Jonas Ådahl, Piotr Drąg, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
127+ Adam Jackson, Robert Mader, Daniel García Moreno, Florian Müllner,
128+ Georges Basile Stavracas Neto, Ray Strode, Marco Trevisan (Treviño),
129+ Daniel van Vugt
130+
131+Translators:
132+ Daniel Mustieles [es], Fabio Tomat [fur], Kukuh Syafaat [id]
133
134 3.32.1
135 ======
136diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c
137index 548615f..1c21378 100644
138--- a/clutter/clutter/cally/cally-actor.c
139+++ b/clutter/clutter/cally/cally-actor.c
140@@ -1044,10 +1044,8 @@ _cally_actor_clean_action_list (CallyActor *cally_actor)
141
142 if (priv->action_list)
143 {
144- g_list_foreach (priv->action_list,
145- (GFunc) _cally_actor_destroy_action_info,
146- NULL);
147- g_list_free (priv->action_list);
148+ g_list_free_full (priv->action_list,
149+ (GDestroyNotify) _cally_actor_destroy_action_info);
150 priv->action_list = NULL;
151 }
152 }
153diff --git a/clutter/clutter/clutter-actor-meta.c b/clutter/clutter/clutter-actor-meta.c
154index 4650d90..d7f4fd7 100644
155--- a/clutter/clutter/clutter-actor-meta.c
156+++ b/clutter/clutter/clutter-actor-meta.c
157@@ -577,8 +577,7 @@ _clutter_meta_group_clear_metas (ClutterMetaGroup *group)
158 {
159 g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
160
161- g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
162- g_list_free (group->meta);
163+ g_list_free_full (group->meta, g_object_unref);
164 group->meta = NULL;
165 }
166
167diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
168index 803f76a..4314969 100644
169--- a/clutter/clutter/clutter-actor.c
170+++ b/clutter/clutter/clutter-actor.c
171@@ -433,7 +433,7 @@
172 *
173 * #ClutterActor allows accessing properties of #ClutterAction,
174 * #ClutterEffect, and #ClutterConstraint instances associated to an actor
175- * instance for animation purposes.
176+ * instance for animation purposes, as well as its #ClutterLayoutManager.
177 *
178 * In order to access a specific #ClutterAction or a #ClutterConstraint
179 * property it is necessary to set the #ClutterActorMeta:name property on the
180@@ -457,6 +457,13 @@
181 * on the `origin` actor, and in its initial state is overlapping the actor
182 * to which is bound to.
183 *
184+ * As the actor has only one #ClutterLayoutManager, the syntax for accessing its
185+ * properties is simpler:
186+ *
187+ * |[
188+ * @layout.<property-name>
189+ * ]|
190+ *
191 * |[<!-- language="C" -->
192 * constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_X, 0.0);
193 * clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-x");
194@@ -807,6 +814,9 @@ struct _ClutterActorPrivate
195 gpointer create_child_data;
196 GDestroyNotify create_child_notify;
197
198+ guint resolution_changed_id;
199+ guint font_changed_id;
200+
201 /* bitfields: KEEP AT THE END */
202
203 /* fixed position and sizes */
204@@ -5983,6 +5993,7 @@ clutter_actor_dispose (GObject *object)
205 {
206 ClutterActor *self = CLUTTER_ACTOR (object);
207 ClutterActorPrivate *priv = self->priv;
208+ ClutterBackend *backend = clutter_get_default_backend ();
209
210 CLUTTER_NOTE (MISC, "Dispose actor (name='%s', ref_count:%d) of type '%s'",
211 _clutter_actor_get_debug_name (self),
212@@ -6019,6 +6030,18 @@ clutter_actor_dispose (GObject *object)
213 g_assert (!CLUTTER_ACTOR_IS_REALIZED (self));
214 }
215
216+ if (priv->resolution_changed_id)
217+ {
218+ g_signal_handler_disconnect (backend, priv->resolution_changed_id);
219+ priv->resolution_changed_id = 0;
220+ }
221+
222+ if (priv->font_changed_id)
223+ {
224+ g_signal_handler_disconnect (backend, priv->font_changed_id);
225+ priv->font_changed_id = 0;
226+ }
227+
228 g_clear_object (&priv->pango_context);
229 g_clear_object (&priv->actions);
230 g_clear_object (&priv->constraints);
231@@ -8833,9 +8856,9 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
232 *
233 * later during _clutter_stage_do_update(), once relayouting is done
234 * and the scenegraph has been updated we will call:
235- * _clutter_stage_finish_queue_redraws().
236+ * clutter_stage_maybe_finish_queue_redraws().
237 *
238- * _clutter_stage_finish_queue_redraws() will call
239+ * clutter_stage_maybe_finish_queue_redraws() will call
240 * _clutter_actor_finish_queue_redraw() for each listed actor.
241 *
242 * Note: actors *are* allowed to queue further redraws during this
243@@ -10091,6 +10114,9 @@ clutter_actor_allocate (ClutterActor *self,
244 return;
245 }
246
247+ if (!clutter_actor_is_visible (self))
248+ return;
249+
250 priv = self->priv;
251
252 old_allocation = priv->allocation;
253@@ -14900,6 +14926,30 @@ clutter_scriptable_iface_init (ClutterScriptableIface *iface)
254 iface->set_custom_property = clutter_actor_set_custom_property;
255 }
256
257+static gboolean
258+get_layout_from_animation_property (ClutterActor *actor,
259+ const gchar *name,
260+ gchar **name_p)
261+{
262+ g_auto (GStrv) tokens = NULL;
263+
264+ if (!g_str_has_prefix (name, "@layout"))
265+ return FALSE;
266+
267+ tokens = g_strsplit (name, ".", -1);
268+ if (tokens == NULL || g_strv_length (tokens) != 2)
269+ {
270+ CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'",
271+ name + 1);
272+ return FALSE;
273+ }
274+
275+ if (name_p != NULL)
276+ *name_p = g_strdup (tokens[1]);
277+
278+ return TRUE;
279+}
280+
281 static ClutterActorMeta *
282 get_meta_from_animation_property (ClutterActor *actor,
283 const gchar *name,
284@@ -14962,14 +15012,21 @@ static GParamSpec *
285 clutter_actor_find_property (ClutterAnimatable *animatable,
286 const gchar *property_name)
287 {
288+ ClutterActor *actor = CLUTTER_ACTOR (animatable);
289 ClutterActorMeta *meta = NULL;
290 GObjectClass *klass = NULL;
291 GParamSpec *pspec = NULL;
292 gchar *p_name = NULL;
293+ gboolean use_layout;
294+
295+ use_layout = get_layout_from_animation_property (actor,
296+ property_name,
297+ &p_name);
298
299- meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable),
300- property_name,
301- &p_name);
302+ if (!use_layout)
303+ meta = get_meta_from_animation_property (actor,
304+ property_name,
305+ &p_name);
306
307 if (meta != NULL)
308 {
309@@ -14977,6 +15034,12 @@ clutter_actor_find_property (ClutterAnimatable *animatable,
310
311 pspec = g_object_class_find_property (klass, p_name);
312 }
313+ else if (use_layout)
314+ {
315+ klass = G_OBJECT_GET_CLASS (actor->priv->layout_manager);
316+
317+ pspec = g_object_class_find_property (klass, p_name);
318+ }
319 else
320 {
321 klass = G_OBJECT_GET_CLASS (animatable);
322@@ -14994,15 +15057,24 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
323 const gchar *property_name,
324 GValue *initial)
325 {
326+ ClutterActor *actor = CLUTTER_ACTOR (animatable);
327 ClutterActorMeta *meta = NULL;
328 gchar *p_name = NULL;
329+ gboolean use_layout;
330+
331+ use_layout = get_layout_from_animation_property (actor,
332+ property_name,
333+ &p_name);
334
335- meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable),
336- property_name,
337- &p_name);
338+ if (!use_layout)
339+ meta = get_meta_from_animation_property (actor,
340+ property_name,
341+ &p_name);
342
343 if (meta != NULL)
344 g_object_get_property (G_OBJECT (meta), p_name, initial);
345+ else if (use_layout)
346+ g_object_get_property (G_OBJECT (actor->priv->layout_manager), p_name, initial);
347 else
348 g_object_get_property (G_OBJECT (animatable), property_name, initial);
349
350@@ -15155,12 +15227,21 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
351 ClutterActor *actor = CLUTTER_ACTOR (animatable);
352 ClutterActorMeta *meta = NULL;
353 gchar *p_name = NULL;
354+ gboolean use_layout;
355+
356+ use_layout = get_layout_from_animation_property (actor,
357+ property_name,
358+ &p_name);
359+
360+ if (!use_layout)
361+ meta = get_meta_from_animation_property (actor,
362+ property_name,
363+ &p_name);
364
365- meta = get_meta_from_animation_property (actor,
366- property_name,
367- &p_name);
368 if (meta != NULL)
369 g_object_set_property (G_OBJECT (meta), p_name, final);
370+ else if (use_layout)
371+ g_object_set_property (G_OBJECT (actor->priv->layout_manager), p_name, final);
372 else
373 {
374 GObjectClass *obj_class = G_OBJECT_GET_CLASS (animatable);
375@@ -15884,10 +15965,12 @@ clutter_actor_get_pango_context (ClutterActor *self)
376 {
377 priv->pango_context = clutter_actor_create_pango_context (self);
378
379- g_signal_connect_object (backend, "resolution-changed",
380- G_CALLBACK (update_pango_context), priv->pango_context, 0);
381- g_signal_connect_object (backend, "font-changed",
382- G_CALLBACK (update_pango_context), priv->pango_context, 0);
383+ priv->resolution_changed_id =
384+ g_signal_connect_object (backend, "resolution-changed",
385+ G_CALLBACK (update_pango_context), priv->pango_context, 0);
386+ priv->font_changed_id =
387+ g_signal_connect_object (backend, "font-changed",
388+ G_CALLBACK (update_pango_context), priv->pango_context, 0);
389 }
390 else
391 update_pango_context (backend, priv->pango_context);
392@@ -17533,7 +17616,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
393 l != NULL && l->data != priv->current_effect;
394 l = l->next)
395 {
396- if (!_clutter_effect_get_paint_volume (l->data, pv))
397+ if (!_clutter_effect_modify_paint_volume (l->data, pv))
398 {
399 clutter_paint_volume_free (pv);
400 CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
401@@ -17551,7 +17634,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
402 /* otherwise, get the cumulative volume */
403 effects = _clutter_meta_group_peek_metas (priv->effects);
404 for (l = effects; l != NULL; l = l->next)
405- if (!_clutter_effect_get_paint_volume (l->data, pv))
406+ if (!_clutter_effect_modify_paint_volume (l->data, pv))
407 {
408 clutter_paint_volume_free (pv);
409 CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
410diff --git a/clutter/clutter/clutter-backend.c b/clutter/clutter/clutter-backend.c
411index d4b6a2d..8223913 100644
412--- a/clutter/clutter/clutter-backend.c
413+++ b/clutter/clutter/clutter-backend.c
414@@ -1111,7 +1111,7 @@ _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
415 {
416 if (backend->dummy_onscreen == COGL_INVALID_HANDLE)
417 {
418- CoglError *internal_error = NULL;
419+ GError *internal_error = NULL;
420
421 backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1);
422
423@@ -1119,7 +1119,7 @@ _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
424 &internal_error))
425 {
426 g_critical ("Unable to create dummy onscreen: %s", internal_error->message);
427- cogl_error_free (internal_error);
428+ g_error_free (internal_error);
429 return;
430 }
431 }
432diff --git a/clutter/clutter/clutter-binding-pool.c b/clutter/clutter/clutter-binding-pool.c
433index f0ec29a..60144ba 100644
434--- a/clutter/clutter/clutter-binding-pool.c
435+++ b/clutter/clutter/clutter-binding-pool.c
436@@ -235,8 +235,7 @@ clutter_binding_pool_finalize (GObject *gobject)
437
438 g_hash_table_destroy (pool->entries_hash);
439
440- g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL);
441- g_slist_free (pool->entries);
442+ g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free);
443
444 G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject);
445 }
446diff --git a/clutter/clutter/clutter-blur-effect.c b/clutter/clutter/clutter-blur-effect.c
447index 564f796..1ffb99c 100644
448--- a/clutter/clutter/clutter-blur-effect.c
449+++ b/clutter/clutter/clutter-blur-effect.c
450@@ -178,8 +178,8 @@ clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
451 }
452
453 static gboolean
454-clutter_blur_effect_get_paint_volume (ClutterEffect *effect,
455- ClutterPaintVolume *volume)
456+clutter_blur_effect_modify_paint_volume (ClutterEffect *effect,
457+ ClutterPaintVolume *volume)
458 {
459 gfloat cur_width, cur_height;
460 ClutterVertex origin;
461@@ -223,7 +223,7 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
462 gobject_class->dispose = clutter_blur_effect_dispose;
463
464 effect_class->pre_paint = clutter_blur_effect_pre_paint;
465- effect_class->get_paint_volume = clutter_blur_effect_get_paint_volume;
466+ effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
467
468 offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
469 offscreen_class->paint_target = clutter_blur_effect_paint_target;
470@@ -249,9 +249,7 @@ clutter_blur_effect_init (ClutterBlurEffect *self)
471 cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
472 cogl_object_unref (snippet);
473
474- cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
475- 0, /* layer number */
476- COGL_TEXTURE_TYPE_2D);
477+ cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
478 }
479
480 self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
481diff --git a/clutter/clutter/clutter-brightness-contrast-effect.c b/clutter/clutter/clutter-brightness-contrast-effect.c
482index 741a818..9bb3d97 100644
483--- a/clutter/clutter/clutter-brightness-contrast-effect.c
484+++ b/clutter/clutter/clutter-brightness-contrast-effect.c
485@@ -438,9 +438,7 @@ clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
486 cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
487 cogl_object_unref (snippet);
488
489- cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
490- 0, /* layer number */
491- COGL_TEXTURE_TYPE_2D);
492+ cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
493 }
494
495 self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
496diff --git a/clutter/clutter/clutter-click-action.c b/clutter/clutter/clutter-click-action.c
497index f7b73cc..5b4c99f 100644
498--- a/clutter/clutter/clutter-click-action.c
499+++ b/clutter/clutter/clutter-click-action.c
500@@ -355,6 +355,10 @@ on_captured_event (ClutterActor *stage,
501
502 switch (clutter_event_type (event))
503 {
504+ case CLUTTER_TOUCH_CANCEL:
505+ clutter_click_action_release (action);
506+ break;
507+
508 case CLUTTER_TOUCH_END:
509 has_button = FALSE;
510 case CLUTTER_BUTTON_RELEASE:
511diff --git a/clutter/clutter/clutter-clone.c b/clutter/clutter/clutter-clone.c
512index 53dcb6c..40a3d53 100644
513--- a/clutter/clutter/clutter-clone.c
514+++ b/clutter/clutter/clutter-clone.c
515@@ -252,6 +252,13 @@ clutter_clone_allocate (ClutterActor *self,
516 if (priv->clone_source == NULL)
517 return;
518
519+ /* ClutterActor delays allocating until the actor is shown; however
520+ * we cannot paint it correctly in that case, so force an allocation.
521+ */
522+ if (clutter_actor_get_parent (priv->clone_source) != NULL &&
523+ !clutter_actor_has_allocation (priv->clone_source))
524+ clutter_actor_allocate_preferred_size (priv->clone_source, flags);
525+
526 #if 0
527 /* XXX - this is wrong: ClutterClone cannot clone unparented
528 * actors, as it will break all invariants
529diff --git a/clutter/clutter/clutter-colorize-effect.c b/clutter/clutter/clutter-colorize-effect.c
530index 1662f7d..73bd319 100644
531--- a/clutter/clutter/clutter-colorize-effect.c
532+++ b/clutter/clutter/clutter-colorize-effect.c
533@@ -293,9 +293,7 @@ clutter_colorize_effect_init (ClutterColorizeEffect *self)
534 cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
535 cogl_object_unref (snippet);
536
537- cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
538- 0, /* layer number */
539- COGL_TEXTURE_TYPE_2D);
540+ cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
541 }
542
543 self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
544diff --git a/clutter/clutter/clutter-deform-effect.c b/clutter/clutter/clutter-deform-effect.c
545index a52e8b9..05ee15f 100644
546--- a/clutter/clutter/clutter-deform-effect.c
547+++ b/clutter/clutter/clutter-deform-effect.c
548@@ -282,6 +282,7 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
549 /* enable depth testing */
550 cogl_depth_state_init (&depth_state);
551 cogl_depth_state_set_test_enabled (&depth_state, TRUE);
552+ cogl_depth_state_set_test_function (&depth_state, COGL_DEPTH_TEST_FUNCTION_LEQUAL);
553 cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);
554
555 /* enable backface culling if we have a back material */
556diff --git a/clutter/clutter/clutter-deprecated.h b/clutter/clutter/clutter-deprecated.h
557index c26c681..1673be8 100644
558--- a/clutter/clutter/clutter-deprecated.h
559+++ b/clutter/clutter/clutter-deprecated.h
560@@ -17,7 +17,6 @@
561 #include "deprecated/clutter-container.h"
562 #include "deprecated/clutter-group.h"
563 #include "deprecated/clutter-keysyms.h"
564-#include "deprecated/clutter-main.h"
565 #include "deprecated/clutter-rectangle.h"
566 #include "deprecated/clutter-stage-manager.h"
567 #include "deprecated/clutter-stage.h"
568diff --git a/clutter/clutter/clutter-desaturate-effect.c b/clutter/clutter/clutter-desaturate-effect.c
569index 061358a..bc691d5 100644
570--- a/clutter/clutter/clutter-desaturate-effect.c
571+++ b/clutter/clutter/clutter-desaturate-effect.c
572@@ -297,9 +297,7 @@ clutter_desaturate_effect_init (ClutterDesaturateEffect *self)
573 cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
574 cogl_object_unref (snippet);
575
576- cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
577- 0, /* layer number */
578- COGL_TEXTURE_TYPE_2D);
579+ cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
580 }
581
582 self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
583diff --git a/clutter/clutter/clutter-device-manager-private.h b/clutter/clutter/clutter-device-manager-private.h
584index 2364fd2..712dd40 100644
585--- a/clutter/clutter/clutter-device-manager-private.h
586+++ b/clutter/clutter/clutter-device-manager-private.h
587@@ -69,6 +69,22 @@ typedef struct _ClutterTouchInfo
588 gfloat current_y;
589 } ClutterTouchInfo;
590
591+typedef struct _ClutterPtrA11yData
592+{
593+ int n_btn_pressed;
594+ float current_x;
595+ float current_y;
596+
597+ float dwell_x;
598+ float dwell_y;
599+ gboolean dwell_drag_started;
600+ gboolean dwell_gesture_started;
601+ guint dwell_timer;
602+
603+ guint secondary_click_timer;
604+ gboolean secondary_click_triggered;
605+} ClutterPtrA11yData;
606+
607 struct _ClutterInputDevice
608 {
609 GObject parent_instance;
610@@ -143,6 +159,10 @@ struct _ClutterInputDevice
611
612 guint has_cursor : 1;
613 guint is_enabled : 1;
614+
615+ /* Accessiblity */
616+ ClutterVirtualInputDevice *accessibility_virtual_device;
617+ ClutterPtrA11yData *ptr_a11y_data;
618 };
619
620 typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
621diff --git a/clutter/clutter/clutter-device-manager.c b/clutter/clutter/clutter-device-manager.c
622index c676384..fd485a0 100644
623--- a/clutter/clutter/clutter-device-manager.c
624+++ b/clutter/clutter/clutter-device-manager.c
625@@ -47,6 +47,7 @@
626 #include "clutter-stage-private.h"
627 #include "clutter-virtual-input-device.h"
628 #include "clutter-input-device-tool.h"
629+#include "clutter-input-pointer-a11y-private.h"
630
631 struct _ClutterDeviceManagerPrivate
632 {
633@@ -55,6 +56,8 @@ struct _ClutterDeviceManagerPrivate
634
635 /* Keyboard a11y */
636 ClutterKbdA11ySettings kbd_a11y_settings;
637+ /* Pointer a11y */
638+ ClutterPointerA11ySettings pointer_a11y_settings;
639 };
640
641 enum
642@@ -75,6 +78,9 @@ enum
643 TOOL_CHANGED,
644 KBD_A11Y_MASK_CHANGED,
645 KBD_A11Y_FLAGS_CHANGED,
646+ PTR_A11Y_DWELL_CLICK_TYPE_CHANGED,
647+ PTR_A11Y_TIMEOUT_STARTED,
648+ PTR_A11Y_TIMEOUT_STOPPED,
649
650 LAST_SIGNAL
651 };
652@@ -239,6 +245,67 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
653 G_TYPE_NONE, 2,
654 G_TYPE_UINT,
655 G_TYPE_UINT);
656+
657+ /**
658+ * ClutterDeviceManager::ptr-a11y-dwell-click-type-changed:
659+ * @manager: the #ClutterDeviceManager that emitted the signal
660+ * @click_type: the new #ClutterPointerA11yDwellClickType mode
661+ *
662+ * The ::ptr-a11y-dwell-click-type-changed signal is emitted each time
663+ * the ClutterPointerA11yDwellClickType mode is changed as the result
664+ * of pointer accessibility operations.
665+ */
666+ manager_signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] =
667+ g_signal_new (I_("ptr-a11y-dwell-click-type-changed"),
668+ G_TYPE_FROM_CLASS (klass),
669+ G_SIGNAL_RUN_LAST,
670+ 0, NULL, NULL,
671+ g_cclosure_marshal_VOID__FLAGS,
672+ G_TYPE_NONE, 1,
673+ CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE);
674+
675+ /**
676+ * ClutterDeviceManager::ptr-a11y-timeout-started:
677+ * @manager: the #ClutterDeviceManager that emitted the signal
678+ * @device: the core pointer #ClutterInputDevice
679+ * @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
680+ * @delay: the delay in ms before secondary-click is triggered.
681+ *
682+ * The ::ptr-a11y-timeout-started signal is emitted when a
683+ * pointer accessibility timeout delay is started, so that upper
684+ * layers can notify the user with some visual feedback.
685+ */
686+ manager_signals[PTR_A11Y_TIMEOUT_STARTED] =
687+ g_signal_new (I_("ptr-a11y-timeout-started"),
688+ G_TYPE_FROM_CLASS (klass),
689+ G_SIGNAL_RUN_LAST,
690+ 0, NULL, NULL,
691+ _clutter_marshal_VOID__OBJECT_FLAGS_UINT,
692+ G_TYPE_NONE, 3,
693+ CLUTTER_TYPE_INPUT_DEVICE,
694+ CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
695+ G_TYPE_UINT);
696+
697+ /**
698+ * ClutterDeviceManager::ptr-a11y-timeout-stopped:
699+ * @manager: the #ClutterDeviceManager that emitted the signal
700+ * @device: the core pointer #ClutterInputDevice
701+ * @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
702+ *
703+ * The ::ptr-a11y-timeout-stopped signal is emitted when a running
704+ * pointer accessibility timeout delay is stopped, either because
705+ * it's triggered at the end of the delay or cancelled, so that
706+ * upper layers can notify the user with some visual feedback.
707+ */
708+ manager_signals[PTR_A11Y_TIMEOUT_STOPPED] =
709+ g_signal_new (I_("ptr-a11y-timeout-stopped"),
710+ G_TYPE_FROM_CLASS (klass),
711+ G_SIGNAL_RUN_LAST,
712+ 0, NULL, NULL,
713+ _clutter_marshal_VOID__OBJECT_FLAGS,
714+ G_TYPE_NONE, 2,
715+ CLUTTER_TYPE_INPUT_DEVICE,
716+ CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE);
717 }
718
719 static void
720@@ -579,3 +646,88 @@ clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_man
721
722 *settings = device_manager->priv->kbd_a11y_settings;
723 }
724+
725+static gboolean
726+are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a,
727+ ClutterPointerA11ySettings *b)
728+{
729+ return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0);
730+}
731+
732+static void
733+clutter_device_manager_enable_pointer_a11y (ClutterDeviceManager *device_manager)
734+{
735+ ClutterInputDevice *core_pointer;
736+
737+ core_pointer = clutter_device_manager_get_core_device (device_manager,
738+ CLUTTER_POINTER_DEVICE);
739+
740+ _clutter_input_pointer_a11y_add_device (core_pointer);
741+}
742+
743+static void
744+clutter_device_manager_disable_pointer_a11y (ClutterDeviceManager *device_manager)
745+{
746+ ClutterInputDevice *core_pointer;
747+
748+ core_pointer = clutter_device_manager_get_core_device (device_manager,
749+ CLUTTER_POINTER_DEVICE);
750+
751+ _clutter_input_pointer_a11y_remove_device (core_pointer);
752+}
753+
754+/**
755+ * clutter_device_manager_set_pointer_a11y_settings:
756+ * @device_manager: a #ClutterDeviceManager
757+ * @settings: a pointer to a #ClutterPointerA11ySettings
758+ *
759+ * Sets the pointer accessibility settings
760+ **/
761+void
762+clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
763+ ClutterPointerA11ySettings *settings)
764+{
765+ g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
766+
767+ if (are_pointer_a11y_settings_equal (&device_manager->priv->pointer_a11y_settings, settings))
768+ return;
769+
770+ if (device_manager->priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
771+ clutter_device_manager_enable_pointer_a11y (device_manager);
772+ else if (device_manager->priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
773+ clutter_device_manager_disable_pointer_a11y (device_manager);
774+
775+ device_manager->priv->pointer_a11y_settings = *settings;
776+}
777+
778+/**
779+ * clutter_device_manager_get_pointer_a11y_settings:
780+ * @device_manager: a #ClutterDeviceManager
781+ * @settings: a pointer to a #ClutterPointerA11ySettings
782+ *
783+ * Gets the current pointer accessibility settings
784+ **/
785+void
786+clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
787+ ClutterPointerA11ySettings *settings)
788+{
789+ g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
790+
791+ *settings = device_manager->priv->pointer_a11y_settings;
792+}
793+
794+/**
795+ * clutter_device_manager_set_pointer_a11y_dwell_click_type:
796+ * @device_manager: a #ClutterDeviceManager
797+ * @click_type: type of click as #ClutterPointerA11yDwellClickType
798+ *
799+ * Sets the dwell click type
800+ **/
801+void
802+clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
803+ ClutterPointerA11yDwellClickType click_type)
804+{
805+ g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
806+
807+ device_manager->priv->pointer_a11y_settings.dwell_click_type = click_type;
808+}
809diff --git a/clutter/clutter/clutter-device-manager.h b/clutter/clutter/clutter-device-manager.h
810index 1cbf030..5fbd395 100644
811--- a/clutter/clutter/clutter-device-manager.h
812+++ b/clutter/clutter/clutter-device-manager.h
813@@ -74,6 +74,27 @@ typedef struct _ClutterKbdA11ySettings
814 } ClutterKbdA11ySettings;
815
816 /**
817+ * ClutterPointerA11ySettings:
818+ *
819+ * The #ClutterPointerA11ySettings structure contains pointer accessibility
820+ * settings
821+ *
822+ */
823+typedef struct _ClutterPointerA11ySettings
824+{
825+ ClutterPointerA11yFlags controls;
826+ ClutterPointerA11yDwellClickType dwell_click_type;
827+ ClutterPointerA11yDwellMode dwell_mode;
828+ ClutterPointerA11yDwellDirection dwell_gesture_single;
829+ ClutterPointerA11yDwellDirection dwell_gesture_double;
830+ ClutterPointerA11yDwellDirection dwell_gesture_drag;
831+ ClutterPointerA11yDwellDirection dwell_gesture_secondary;
832+ gint secondary_click_delay;
833+ gint dwell_delay;
834+ gint dwell_threshold;
835+} ClutterPointerA11ySettings;
836+
837+/**
838 * ClutterDeviceManager:
839 *
840 * The #ClutterDeviceManager structure contains only private data
841@@ -152,10 +173,23 @@ ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_typ
842 CLUTTER_EXPORT
843 void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
844 ClutterKbdA11ySettings *settings);
845+
846 CLUTTER_EXPORT
847 void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
848 ClutterKbdA11ySettings *settings);
849
850+CLUTTER_EXPORT
851+void clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
852+ ClutterPointerA11ySettings *settings);
853+
854+CLUTTER_EXPORT
855+void clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
856+ ClutterPointerA11ySettings *settings);
857+
858+CLUTTER_EXPORT
859+void clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
860+ ClutterPointerA11yDwellClickType click_type);
861+
862 G_END_DECLS
863
864 #endif /* __CLUTTER_DEVICE_MANAGER_H__ */
865diff --git a/clutter/clutter/clutter-effect-private.h b/clutter/clutter/clutter-effect-private.h
866index c1e9b3b..87f3484 100644
867--- a/clutter/clutter/clutter-effect-private.h
868+++ b/clutter/clutter/clutter-effect-private.h
869@@ -7,7 +7,7 @@ G_BEGIN_DECLS
870
871 gboolean _clutter_effect_pre_paint (ClutterEffect *effect);
872 void _clutter_effect_post_paint (ClutterEffect *effect);
873-gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
874+gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect,
875 ClutterPaintVolume *volume);
876 gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
877 void _clutter_effect_paint (ClutterEffect *effect,
878diff --git a/clutter/clutter/clutter-effect.c b/clutter/clutter/clutter-effect.c
879index 82cf671..a7c06d9 100644
880--- a/clutter/clutter/clutter-effect.c
881+++ b/clutter/clutter/clutter-effect.c
882@@ -188,8 +188,8 @@ clutter_effect_real_post_paint (ClutterEffect *effect)
883 }
884
885 static gboolean
886-clutter_effect_real_get_paint_volume (ClutterEffect *effect,
887- ClutterPaintVolume *volume)
888+clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
889+ ClutterPaintVolume *volume)
890 {
891 return TRUE;
892 }
893@@ -252,7 +252,7 @@ clutter_effect_class_init (ClutterEffectClass *klass)
894
895 klass->pre_paint = clutter_effect_real_pre_paint;
896 klass->post_paint = clutter_effect_real_post_paint;
897- klass->get_paint_volume = clutter_effect_real_get_paint_volume;
898+ klass->modify_paint_volume = clutter_effect_real_modify_paint_volume;
899 klass->paint = clutter_effect_real_paint;
900 klass->pick = clutter_effect_real_pick;
901 }
902@@ -297,13 +297,14 @@ _clutter_effect_pick (ClutterEffect *effect,
903 }
904
905 gboolean
906-_clutter_effect_get_paint_volume (ClutterEffect *effect,
907- ClutterPaintVolume *volume)
908+_clutter_effect_modify_paint_volume (ClutterEffect *effect,
909+ ClutterPaintVolume *volume)
910 {
911 g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
912 g_return_val_if_fail (volume != NULL, FALSE);
913
914- return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
915+ return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume (effect,
916+ volume);
917 }
918
919 gboolean
920@@ -311,7 +312,7 @@ _clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
921 {
922 g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
923
924- return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume != clutter_effect_real_get_paint_volume;
925+ return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume != clutter_effect_real_modify_paint_volume;
926 }
927
928 /**
929diff --git a/clutter/clutter/clutter-effect.h b/clutter/clutter/clutter-effect.h
930index d25a63e..6f280d9 100644
931--- a/clutter/clutter/clutter-effect.h
932+++ b/clutter/clutter/clutter-effect.h
933@@ -60,7 +60,7 @@ struct _ClutterEffect
934 * ClutterEffectClass:
935 * @pre_paint: virtual function
936 * @post_paint: virtual function
937- * @get_paint_volume: virtual function
938+ * @modify_paint_volume: virtual function
939 * @paint: virtual function
940 * @pick: virtual function
941 *
942@@ -74,16 +74,16 @@ struct _ClutterEffectClass
943 ClutterActorMetaClass parent_class;
944
945 /*< public >*/
946- gboolean (* pre_paint) (ClutterEffect *effect);
947- void (* post_paint) (ClutterEffect *effect);
948+ gboolean (* pre_paint) (ClutterEffect *effect);
949+ void (* post_paint) (ClutterEffect *effect);
950
951- gboolean (* get_paint_volume) (ClutterEffect *effect,
952- ClutterPaintVolume *volume);
953+ gboolean (* modify_paint_volume) (ClutterEffect *effect,
954+ ClutterPaintVolume *volume);
955
956- void (* paint) (ClutterEffect *effect,
957- ClutterEffectPaintFlags flags);
958- void (* pick) (ClutterEffect *effect,
959- ClutterEffectPaintFlags flags);
960+ void (* paint) (ClutterEffect *effect,
961+ ClutterEffectPaintFlags flags);
962+ void (* pick) (ClutterEffect *effect,
963+ ClutterEffectPaintFlags flags);
964
965 /*< private >*/
966 void (* _clutter_effect4) (void);
967diff --git a/clutter/clutter/clutter-enum-types.h.in b/clutter/clutter/clutter-enum-types.h.in
968index 2e5b670..17f9ee6 100644
969--- a/clutter/clutter/clutter-enum-types.h.in
970+++ b/clutter/clutter/clutter-enum-types.h.in
971@@ -13,7 +13,7 @@ G_BEGIN_DECLS
972 /*** END file-header ***/
973
974 /*** BEGIN file-production ***/
975-/* enumerations from "@filename@" */
976+/* enumerations from "@basename@" */
977 /*** END file-production ***/
978
979 /*** BEGIN value-header ***/
980diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h
981index 9cb2967..c91f4cb 100644
982--- a/clutter/clutter/clutter-enums.h
983+++ b/clutter/clutter/clutter-enums.h
984@@ -278,24 +278,6 @@ typedef enum
985 } ClutterAnimationMode;
986
987 /**
988- * ClutterFontFlags:
989- * @CLUTTER_FONT_MIPMAPPING: Set to use mipmaps for the glyph cache textures.
990- * @CLUTTER_FONT_HINTING: Set to enable hinting on the glyphs.
991- *
992- * Runtime flags to change the font quality. To be used with
993- * clutter_set_font_flags().
994- *
995- * Since: 1.0
996- *
997- * Deprecated: 1.22: Use #cairo_font_options_t instead
998- */
999-typedef enum /*< prefix=CLUTTER_FONT >*/
1000-{
1001- CLUTTER_FONT_MIPMAPPING = (1 << 0),
1002- CLUTTER_FONT_HINTING = (1 << 1)
1003-} ClutterFontFlags;
1004-
1005-/**
1006 * ClutterTextDirection:
1007 * @CLUTTER_TEXT_DIRECTION_DEFAULT: Use the default setting, as returned
1008 * by clutter_get_default_text_direction()
1009@@ -444,6 +426,88 @@ typedef enum
1010 } ClutterKeyboardA11yFlags;
1011
1012 /**
1013+ * ClutterPointerA11yFlags:
1014+ * @CLUTTER_A11Y_POINTER_ENABLED:
1015+ * @CLUTTER_A11Y_SECONDARY_CLICK_ENABLED:
1016+ * @CLUTTER_A11Y_DWELL_ENABLED:
1017+ *
1018+ * Pointer accessibility features applied to a ClutterInputDevice pointer.
1019+ *
1020+ */
1021+typedef enum {
1022+ CLUTTER_A11Y_SECONDARY_CLICK_ENABLED = 1 << 0,
1023+ CLUTTER_A11Y_DWELL_ENABLED = 1 << 1,
1024+} ClutterPointerA11yFlags;
1025+
1026+/**
1027+ * ClutterPointerA11yDwellClickType:
1028+ * @CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: Internal use only
1029+ * @CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
1030+ * @CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
1031+ * @CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
1032+ * @CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
1033+ * @CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
1034+ *
1035+ * Dwell click types.
1036+ *
1037+ */
1038+typedef enum {
1039+ CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE,
1040+ CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY,
1041+ CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY,
1042+ CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE,
1043+ CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE,
1044+ CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG,
1045+} ClutterPointerA11yDwellClickType;
1046+
1047+/**
1048+ * ClutterPointerA11yDwellDirection:
1049+ * @CLUTTER_A11Y_DWELL_DIRECTION_NONE:
1050+ * @CLUTTER_A11Y_DWELL_DIRECTION_LEFT:
1051+ * @CLUTTER_A11Y_DWELL_DIRECTION_RIGHT:
1052+ * @CLUTTER_A11Y_DWELL_DIRECTION_UP:
1053+ * @CLUTTER_A11Y_DWELL_DIRECTION_DOWN:
1054+ *
1055+ * Dwell gesture directions.
1056+ *
1057+ */
1058+typedef enum {
1059+ CLUTTER_A11Y_DWELL_DIRECTION_NONE,
1060+ CLUTTER_A11Y_DWELL_DIRECTION_LEFT,
1061+ CLUTTER_A11Y_DWELL_DIRECTION_RIGHT,
1062+ CLUTTER_A11Y_DWELL_DIRECTION_UP,
1063+ CLUTTER_A11Y_DWELL_DIRECTION_DOWN,
1064+} ClutterPointerA11yDwellDirection;
1065+
1066+/**
1067+ * ClutterPointerA11yDwellMode:
1068+ * @CLUTTER_A11Y_DWELL_MODE_WINDOW:
1069+ * @CLUTTER_A11Y_DWELL_MODE_GESTURE:
1070+ *
1071+ * Dwell mode.
1072+ *
1073+ */
1074+typedef enum {
1075+ CLUTTER_A11Y_DWELL_MODE_WINDOW,
1076+ CLUTTER_A11Y_DWELL_MODE_GESTURE,
1077+} ClutterPointerA11yDwellMode;
1078+
1079+/**
1080+ * ClutterPointerA11yTimeoutType:
1081+ * @CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK:
1082+ * @CLUTTER_A11Y_TIMEOUT_TYPE_DWELL:
1083+ * @CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE:
1084+ *
1085+ * Pointer accessibility timeout type.
1086+ *
1087+ */
1088+typedef enum {
1089+ CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
1090+ CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
1091+ CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
1092+} ClutterPointerA11yTimeoutType;
1093+
1094+/**
1095 * ClutterActorFlags:
1096 * @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
1097 * a toplevel, and all parents visible)
1098@@ -892,8 +956,6 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
1099
1100 /**
1101 * ClutterStageState:
1102- * @CLUTTER_STAGE_STATE_FULLSCREEN: Fullscreen mask
1103- * @CLUTTER_STAGE_STATE_OFFSCREEN: Offscreen mask (deprecated)
1104 * @CLUTTER_STAGE_STATE_ACTIVATED: Activated mask
1105 *
1106 * Stage state masks, used by the #ClutterEvent of type %CLUTTER_STAGE_STATE.
1107@@ -902,19 +964,15 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
1108 */
1109 typedef enum
1110 {
1111- CLUTTER_STAGE_STATE_FULLSCREEN = (1 << 1),
1112- CLUTTER_STAGE_STATE_OFFSCREEN = (1 << 2),
1113 CLUTTER_STAGE_STATE_ACTIVATED = (1 << 3)
1114 } ClutterStageState;
1115
1116 /**
1117 * ClutterFeatureFlags:
1118- * @CLUTTER_FEATURE_TEXTURE_NPOT: Set if NPOTS textures supported.
1119 * @CLUTTER_FEATURE_SWAP_THROTTLE: Set if backend throttles buffer swaps.
1120 * @CLUTTER_FEATURE_TEXTURE_YUV: Set if YUV based textures supported.
1121 * @CLUTTER_FEATURE_TEXTURE_READ_PIXELS: Set if texture pixels can be read.
1122 * @CLUTTER_FEATURE_STAGE_STATIC: Set if stage size if fixed (i.e framebuffer)
1123- * @CLUTTER_FEATURE_STAGE_USER_RESIZE: Set if stage is able to be user resized.
1124 * @CLUTTER_FEATURE_STAGE_CURSOR: Set if stage has a graphical cursor.
1125 * @CLUTTER_FEATURE_SHADERS_GLSL: Set if the backend supports GLSL shaders.
1126 * @CLUTTER_FEATURE_OFFSCREEN: Set if the backend supports offscreen rendering.
1127@@ -928,12 +986,10 @@ typedef enum
1128 */
1129 typedef enum
1130 {
1131- CLUTTER_FEATURE_TEXTURE_NPOT = (1 << 2),
1132 CLUTTER_FEATURE_SWAP_THROTTLE = (1 << 3),
1133 CLUTTER_FEATURE_TEXTURE_YUV = (1 << 4),
1134 CLUTTER_FEATURE_TEXTURE_READ_PIXELS = (1 << 5),
1135 CLUTTER_FEATURE_STAGE_STATIC = (1 << 6),
1136- CLUTTER_FEATURE_STAGE_USER_RESIZE = (1 << 7),
1137 CLUTTER_FEATURE_STAGE_CURSOR = (1 << 8),
1138 CLUTTER_FEATURE_SHADERS_GLSL = (1 << 9),
1139 CLUTTER_FEATURE_OFFSCREEN = (1 << 10),
1140diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c
1141index 8e7782d..8ccf0e8 100644
1142--- a/clutter/clutter/clutter-event.c
1143+++ b/clutter/clutter/clutter-event.c
1144@@ -1021,6 +1021,9 @@ clutter_event_get_event_sequence (const ClutterEvent *event)
1145 event->type == CLUTTER_TOUCH_END ||
1146 event->type == CLUTTER_TOUCH_CANCEL)
1147 return event->touch.sequence;
1148+ else if (event->type == CLUTTER_ENTER ||
1149+ event->type == CLUTTER_LEAVE)
1150+ return event->crossing.sequence;
1151
1152 return NULL;
1153 }
1154diff --git a/clutter/clutter/clutter-event.h b/clutter/clutter/clutter-event.h
1155index 15596d9..54155cd 100644
1156--- a/clutter/clutter/clutter-event.h
1157+++ b/clutter/clutter/clutter-event.h
1158@@ -269,6 +269,7 @@ struct _ClutterCrossingEvent
1159 gfloat x;
1160 gfloat y;
1161 ClutterInputDevice *device;
1162+ ClutterEventSequence *sequence;
1163 ClutterActor *related;
1164 };
1165
1166diff --git a/clutter/clutter/clutter-feature.c b/clutter/clutter/clutter-feature.c
1167index 6ce7627..5741391 100644
1168--- a/clutter/clutter/clutter-feature.c
1169+++ b/clutter/clutter/clutter-feature.c
1170@@ -64,17 +64,13 @@ clutter_features_from_cogl (guint cogl_flags)
1171 {
1172 ClutterFeatureFlags clutter_flags = 0;
1173
1174- if (cogl_flags & COGL_FEATURE_TEXTURE_NPOT)
1175- clutter_flags |= CLUTTER_FEATURE_TEXTURE_NPOT;
1176-
1177 if (cogl_flags & COGL_FEATURE_TEXTURE_YUV)
1178 clutter_flags |= CLUTTER_FEATURE_TEXTURE_YUV;
1179
1180 if (cogl_flags & COGL_FEATURE_TEXTURE_READ_PIXELS)
1181 clutter_flags |= CLUTTER_FEATURE_TEXTURE_READ_PIXELS;
1182
1183- if (cogl_flags & COGL_FEATURE_SHADERS_GLSL)
1184- clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL;
1185+ clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL;
1186
1187 if (cogl_flags & COGL_FEATURE_OFFSCREEN)
1188 clutter_flags |= CLUTTER_FEATURE_OFFSCREEN;
1189diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c
1190index 0697e3a..c289f81 100644
1191--- a/clutter/clutter/clutter-input-device.c
1192+++ b/clutter/clutter/clutter-input-device.c
1193@@ -107,6 +107,9 @@ clutter_input_device_dispose (GObject *gobject)
1194 device->associated = NULL;
1195 }
1196
1197+ if (device->accessibility_virtual_device)
1198+ g_clear_object (&device->accessibility_virtual_device);
1199+
1200 g_clear_pointer (&device->axes, g_array_unref);
1201 g_clear_pointer (&device->keys, g_array_unref);
1202 g_clear_pointer (&device->scroll_info, g_array_unref);
1203@@ -834,6 +837,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
1204 event->crossing.x = device->current_x;
1205 event->crossing.y = device->current_y;
1206 event->crossing.related = actor;
1207+ event->crossing.sequence = sequence;
1208 clutter_event_set_device (event, device);
1209
1210 /* we need to make sure that this event is processed
1211@@ -870,6 +874,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
1212 event->crossing.y = device->current_y;
1213 event->crossing.source = actor;
1214 event->crossing.related = old_actor;
1215+ event->crossing.sequence = sequence;
1216 clutter_event_set_device (event, device);
1217
1218 /* see above */
1219@@ -1034,9 +1039,10 @@ _clutter_input_device_update (ClutterInputDevice *device,
1220 ClutterActor *new_cursor_actor;
1221 ClutterActor *old_cursor_actor;
1222 ClutterPoint point = { -1, -1 };
1223+ ClutterInputDeviceType device_type = device->device_type;
1224
1225- if (device->device_type == CLUTTER_KEYBOARD_DEVICE)
1226- return NULL;
1227+ g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
1228+ device_type != CLUTTER_PAD_DEVICE);
1229
1230 stage = device->stage;
1231 if (G_UNLIKELY (stage == NULL))
1232diff --git a/clutter/clutter/clutter-input-pointer-a11y-private.h b/clutter/clutter/clutter-input-pointer-a11y-private.h
1233new file mode 100644
1234index 0000000..6648909
1235--- /dev/null
1236+++ b/clutter/clutter/clutter-input-pointer-a11y-private.h
1237@@ -0,0 +1,42 @@
1238+/*
1239+ * Copyright (C) 2019 Red Hat
1240+ *
1241+ * This program is free software; you can redistribute it and/or
1242+ * modify it under the terms of the GNU General Public License as
1243+ * published by the Free Software Foundation; either version 2 of the
1244+ * License, or (at your option) any later version.
1245+ *
1246+ * This program is distributed in the hope that it will be useful, but
1247+ * WITHOUT ANY WARRANTY; without even the implied warranty of
1248+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1249+ * General Public License for more details.
1250+ *
1251+ * You should have received a copy of the GNU General Public License
1252+ * along with this program; if not, write to the Free Software
1253+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1254+ * 02111-1307, USA.
1255+ *
1256+ * Author: Olivier Fourdan <ofourdan@redhat.com>
1257+ */
1258+
1259+#ifndef __CLUTTER_INPUT_POINTER_A11Y_H__
1260+#define __CLUTTER_INPUT_POINTER_A11Y_H__
1261+
1262+#include <clutter/clutter-types.h>
1263+#include "clutter-enum-types.h"
1264+
1265+G_BEGIN_DECLS
1266+
1267+void _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device);
1268+void _clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device);
1269+void _clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
1270+ float x,
1271+ float y);
1272+void _clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
1273+ int button,
1274+ gboolean pressed);
1275+gboolean _clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device);
1276+
1277+G_END_DECLS
1278+
1279+#endif /* __CLUTTER_INPUT_POINTER_A11Y_H__ */
1280diff --git a/clutter/clutter/clutter-input-pointer-a11y.c b/clutter/clutter/clutter-input-pointer-a11y.c
1281new file mode 100644
1282index 0000000..e55e0a6
1283--- /dev/null
1284+++ b/clutter/clutter/clutter-input-pointer-a11y.c
1285@@ -0,0 +1,669 @@
1286+/*
1287+ * Copyright (C) 2019 Red Hat
1288+ *
1289+ * This program is free software; you can redistribute it and/or
1290+ * modify it under the terms of the GNU General Public License as
1291+ * published by the Free Software Foundation; either version 2 of the
1292+ * License, or (at your option) any later version.
1293+ *
1294+ * This program is distributed in the hope that it will be useful, but
1295+ * WITHOUT ANY WARRANTY; without even the implied warranty of
1296+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1297+ * General Public License for more details.
1298+ *
1299+ * You should have received a copy of the GNU General Public License
1300+ * along with this program; if not, write to the Free Software
1301+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1302+ * 02111-1307, USA.
1303+ *
1304+ * Author: Olivier Fourdan <ofourdan@redhat.com>
1305+ *
1306+ * This reimplements in Clutter the same behavior as mousetweaks original
1307+ * implementation by Gerd Kohlberger <gerdko gmail com>
1308+ * mousetweaks Copyright (C) 2007-2010 Gerd Kohlberger <gerdko gmail com>
1309+ */
1310+
1311+#include "clutter-build-config.h"
1312+
1313+#include "clutter-device-manager.h"
1314+#include "clutter-device-manager-private.h"
1315+#include "clutter-enum-types.h"
1316+#include "clutter-input-device.h"
1317+#include "clutter-input-pointer-a11y-private.h"
1318+#include "clutter-main.h"
1319+#include "clutter-virtual-input-device.h"
1320+
1321+static gboolean
1322+is_secondary_click_enabled (ClutterInputDevice *device)
1323+{
1324+ ClutterPointerA11ySettings settings;
1325+
1326+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1327+
1328+ return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED);
1329+}
1330+
1331+static gboolean
1332+is_dwell_click_enabled (ClutterInputDevice *device)
1333+{
1334+ ClutterPointerA11ySettings settings;
1335+
1336+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1337+
1338+ return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED);
1339+}
1340+
1341+static unsigned int
1342+get_secondary_click_delay (ClutterInputDevice *device)
1343+{
1344+ ClutterPointerA11ySettings settings;
1345+
1346+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1347+
1348+ return settings.secondary_click_delay;
1349+}
1350+
1351+static unsigned int
1352+get_dwell_delay (ClutterInputDevice *device)
1353+{
1354+ ClutterPointerA11ySettings settings;
1355+
1356+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1357+
1358+ return settings.dwell_delay;
1359+}
1360+
1361+static unsigned int
1362+get_dwell_threshold (ClutterInputDevice *device)
1363+{
1364+ ClutterPointerA11ySettings settings;
1365+
1366+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1367+
1368+ return settings.dwell_threshold;
1369+}
1370+
1371+static ClutterPointerA11yDwellMode
1372+get_dwell_mode (ClutterInputDevice *device)
1373+{
1374+ ClutterPointerA11ySettings settings;
1375+
1376+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1377+
1378+ return settings.dwell_mode;
1379+}
1380+
1381+static ClutterPointerA11yDwellClickType
1382+get_dwell_click_type (ClutterInputDevice *device)
1383+{
1384+ ClutterPointerA11ySettings settings;
1385+
1386+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1387+#
1388+ return settings.dwell_click_type;
1389+}
1390+
1391+static ClutterPointerA11yDwellClickType
1392+get_dwell_click_type_for_direction (ClutterInputDevice *device,
1393+ ClutterPointerA11yDwellDirection direction)
1394+{
1395+ ClutterPointerA11ySettings settings;
1396+
1397+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1398+
1399+ if (direction == settings.dwell_gesture_single)
1400+ return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
1401+ else if (direction == settings.dwell_gesture_double)
1402+ return CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE;
1403+ else if (direction == settings.dwell_gesture_drag)
1404+ return CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG;
1405+ else if (direction == settings.dwell_gesture_secondary)
1406+ return CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY;
1407+
1408+ return CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE;
1409+}
1410+
1411+static void
1412+emit_button_press (ClutterInputDevice *device,
1413+ gint button)
1414+{
1415+ clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
1416+ g_get_monotonic_time (),
1417+ button,
1418+ CLUTTER_BUTTON_STATE_PRESSED);
1419+}
1420+
1421+static void
1422+emit_button_release (ClutterInputDevice *device,
1423+ gint button)
1424+{
1425+ clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
1426+ g_get_monotonic_time (),
1427+ button,
1428+ CLUTTER_BUTTON_STATE_RELEASED);
1429+}
1430+
1431+static void
1432+emit_button_click (ClutterInputDevice *device,
1433+ gint button)
1434+{
1435+ emit_button_press (device, button);
1436+ emit_button_release (device, button);
1437+}
1438+
1439+static void
1440+restore_dwell_position (ClutterInputDevice *device)
1441+{
1442+ clutter_virtual_input_device_notify_absolute_motion (device->accessibility_virtual_device,
1443+ g_get_monotonic_time (),
1444+ device->ptr_a11y_data->dwell_x,
1445+ device->ptr_a11y_data->dwell_y);
1446+}
1447+
1448+static gboolean
1449+trigger_secondary_click (gpointer data)
1450+{
1451+ ClutterInputDevice *device = data;
1452+
1453+ device->ptr_a11y_data->secondary_click_triggered = TRUE;
1454+ device->ptr_a11y_data->secondary_click_timer = 0;
1455+
1456+ g_signal_emit_by_name (device->device_manager,
1457+ "ptr-a11y-timeout-stopped",
1458+ device,
1459+ CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
1460+
1461+ return G_SOURCE_REMOVE;
1462+}
1463+
1464+static void
1465+start_secondary_click_timeout (ClutterInputDevice *device)
1466+{
1467+ unsigned int delay = get_secondary_click_delay (device);
1468+
1469+ device->ptr_a11y_data->secondary_click_timer =
1470+ clutter_threads_add_timeout (delay, trigger_secondary_click, device);
1471+
1472+ g_signal_emit_by_name (device->device_manager,
1473+ "ptr-a11y-timeout-started",
1474+ device,
1475+ CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
1476+ delay);
1477+}
1478+
1479+static void
1480+stop_secondary_click_timeout (ClutterInputDevice *device)
1481+{
1482+ if (device->ptr_a11y_data->secondary_click_timer)
1483+ {
1484+ g_source_remove (device->ptr_a11y_data->secondary_click_timer);
1485+ device->ptr_a11y_data->secondary_click_timer = 0;
1486+
1487+ g_signal_emit_by_name (device->device_manager,
1488+ "ptr-a11y-timeout-stopped",
1489+ device,
1490+ CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
1491+ }
1492+ device->ptr_a11y_data->secondary_click_triggered = FALSE;
1493+}
1494+
1495+static gboolean
1496+pointer_has_moved (ClutterInputDevice *device)
1497+{
1498+ float dx, dy;
1499+ gint threshold;
1500+
1501+ dx = device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x;
1502+ dy = device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y;
1503+ threshold = get_dwell_threshold (device);
1504+
1505+ /* Pythagorean theorem */
1506+ return ((dx * dx) + (dy * dy)) > (threshold * threshold);
1507+}
1508+
1509+static gboolean
1510+is_secondary_click_pending (ClutterInputDevice *device)
1511+{
1512+ return device->ptr_a11y_data->secondary_click_timer != 0;
1513+}
1514+
1515+static gboolean
1516+is_secondary_click_triggered (ClutterInputDevice *device)
1517+{
1518+ return device->ptr_a11y_data->secondary_click_triggered;
1519+}
1520+
1521+static gboolean
1522+is_dwell_click_pending (ClutterInputDevice *device)
1523+{
1524+ return device->ptr_a11y_data->dwell_timer != 0;
1525+}
1526+
1527+static gboolean
1528+is_dwell_dragging (ClutterInputDevice *device)
1529+{
1530+ return device->ptr_a11y_data->dwell_drag_started;
1531+}
1532+
1533+static gboolean
1534+is_dwell_gesturing (ClutterInputDevice *device)
1535+{
1536+ return device->ptr_a11y_data->dwell_gesture_started;
1537+}
1538+
1539+static gboolean
1540+has_button_pressed (ClutterInputDevice *device)
1541+{
1542+ return device->ptr_a11y_data->n_btn_pressed > 0;
1543+}
1544+
1545+static gboolean
1546+should_start_secondary_click_timeout (ClutterInputDevice *device)
1547+{
1548+ return !is_dwell_dragging (device);
1549+}
1550+
1551+static gboolean
1552+should_start_dwell (ClutterInputDevice *device)
1553+{
1554+ /* We should trigger a dwell if we've not already started one, and if
1555+ * no button is currently pressed or we are in the middle of a dwell
1556+ * drag action.
1557+ */
1558+ return !is_dwell_click_pending (device) &&
1559+ (is_dwell_dragging (device) ||
1560+ !has_button_pressed (device));
1561+}
1562+
1563+static gboolean
1564+should_stop_dwell (ClutterInputDevice *device)
1565+{
1566+ /* We should stop a dwell if the motion exceeds the threshold, unless
1567+ * we've started a gesture, because we want to keep the original dwell
1568+ * location to both detect a gesture and restore the original pointer
1569+ * location once the gesture is finished.
1570+ */
1571+ return pointer_has_moved (device) &&
1572+ !is_dwell_gesturing (device);
1573+}
1574+
1575+
1576+static gboolean
1577+should_update_dwell_position (ClutterInputDevice *device)
1578+{
1579+ return !is_dwell_gesturing (device) &&
1580+ !is_dwell_click_pending (device) &&
1581+ !is_secondary_click_pending (device);
1582+}
1583+
1584+static void
1585+update_dwell_click_type (ClutterInputDevice *device)
1586+{
1587+ ClutterPointerA11ySettings settings;
1588+ ClutterPointerA11yDwellClickType dwell_click_type;
1589+
1590+ clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
1591+
1592+ dwell_click_type = settings.dwell_click_type;
1593+ switch (dwell_click_type)
1594+ {
1595+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
1596+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
1597+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
1598+ dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
1599+ break;
1600+
1601+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
1602+ if (!is_dwell_dragging (device))
1603+ dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
1604+ break;
1605+
1606+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
1607+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
1608+ default:
1609+ break;
1610+ }
1611+
1612+ if (dwell_click_type != settings.dwell_click_type)
1613+ {
1614+ settings.dwell_click_type = dwell_click_type;
1615+ clutter_device_manager_set_pointer_a11y_settings (device->device_manager,
1616+ &settings);
1617+
1618+ g_signal_emit_by_name (device->device_manager,
1619+ "ptr-a11y-dwell-click-type-changed",
1620+ dwell_click_type);
1621+ }
1622+}
1623+
1624+static void
1625+emit_dwell_click (ClutterInputDevice *device,
1626+ ClutterPointerA11yDwellClickType dwell_click_type)
1627+{
1628+ switch (dwell_click_type)
1629+ {
1630+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
1631+ emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
1632+ break;
1633+
1634+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
1635+ emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
1636+ emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
1637+ break;
1638+
1639+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
1640+ if (is_dwell_dragging (device))
1641+ {
1642+ emit_button_release (device, CLUTTER_BUTTON_PRIMARY);
1643+ device->ptr_a11y_data->dwell_drag_started = FALSE;
1644+ }
1645+ else
1646+ {
1647+ emit_button_press (device, CLUTTER_BUTTON_PRIMARY);
1648+ device->ptr_a11y_data->dwell_drag_started = TRUE;
1649+ }
1650+ break;
1651+
1652+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
1653+ emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
1654+ break;
1655+
1656+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
1657+ emit_button_click (device, CLUTTER_BUTTON_MIDDLE);
1658+ break;
1659+
1660+ case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
1661+ default:
1662+ break;
1663+ }
1664+}
1665+
1666+static ClutterPointerA11yDwellDirection
1667+get_dwell_direction (ClutterInputDevice *device)
1668+{
1669+ float dx, dy;
1670+
1671+ dx = ABS (device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x);
1672+ dy = ABS (device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y);
1673+
1674+ /* The pointer hasn't moved */
1675+ if (!pointer_has_moved (device))
1676+ return CLUTTER_A11Y_DWELL_DIRECTION_NONE;
1677+
1678+ if (device->ptr_a11y_data->dwell_x < device->ptr_a11y_data->current_x)
1679+ {
1680+ if (dx > dy)
1681+ return CLUTTER_A11Y_DWELL_DIRECTION_LEFT;
1682+ }
1683+ else
1684+ {
1685+ if (dx > dy)
1686+ return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT;
1687+ }
1688+
1689+ if (device->ptr_a11y_data->dwell_y < device->ptr_a11y_data->current_y)
1690+ return CLUTTER_A11Y_DWELL_DIRECTION_UP;
1691+
1692+ return CLUTTER_A11Y_DWELL_DIRECTION_DOWN;
1693+}
1694+
1695+static gboolean
1696+trigger_clear_dwell_gesture (gpointer data)
1697+{
1698+ ClutterInputDevice *device = data;
1699+
1700+ device->ptr_a11y_data->dwell_timer = 0;
1701+ device->ptr_a11y_data->dwell_gesture_started = FALSE;
1702+
1703+ return G_SOURCE_REMOVE;
1704+}
1705+
1706+static gboolean
1707+trigger_dwell_gesture (gpointer data)
1708+{
1709+ ClutterInputDevice *device = data;
1710+ ClutterPointerA11yDwellDirection direction;
1711+ unsigned int delay = get_dwell_delay (device);
1712+
1713+ restore_dwell_position (device);
1714+ direction = get_dwell_direction (device);
1715+ emit_dwell_click (device,
1716+ get_dwell_click_type_for_direction (device,
1717+ direction));
1718+
1719+ /* Do not clear the gesture right away, otherwise we'll start another one */
1720+ device->ptr_a11y_data->dwell_timer =
1721+ clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device);
1722+
1723+ g_signal_emit_by_name (device->device_manager,
1724+ "ptr-a11y-timeout-stopped",
1725+ device,
1726+ CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE);
1727+
1728+ return G_SOURCE_REMOVE;
1729+}
1730+
1731+static void
1732+start_dwell_gesture_timeout (ClutterInputDevice *device)
1733+{
1734+ unsigned int delay = get_dwell_delay (device);
1735+
1736+ device->ptr_a11y_data->dwell_timer =
1737+ clutter_threads_add_timeout (delay, trigger_dwell_gesture, device);
1738+ device->ptr_a11y_data->dwell_gesture_started = TRUE;
1739+
1740+ g_signal_emit_by_name (device->device_manager,
1741+ "ptr-a11y-timeout-started",
1742+ device,
1743+ CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
1744+ delay);
1745+}
1746+
1747+static gboolean
1748+trigger_dwell_click (gpointer data)
1749+{
1750+ ClutterInputDevice *device = data;
1751+
1752+ device->ptr_a11y_data->dwell_timer = 0;
1753+
1754+ g_signal_emit_by_name (device->device_manager,
1755+ "ptr-a11y-timeout-stopped",
1756+ device,
1757+ CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
1758+
1759+ if (get_dwell_mode (device) == CLUTTER_A11Y_DWELL_MODE_GESTURE)
1760+ {
1761+ if (is_dwell_dragging (device))
1762+ emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
1763+ else
1764+ start_dwell_gesture_timeout (device);
1765+ }
1766+ else
1767+ {
1768+ emit_dwell_click (device, get_dwell_click_type (device));
1769+ update_dwell_click_type (device);
1770+ }
1771+
1772+ return G_SOURCE_REMOVE;
1773+}
1774+
1775+static void
1776+start_dwell_timeout (ClutterInputDevice *device)
1777+{
1778+ unsigned int delay = get_dwell_delay (device);
1779+
1780+ device->ptr_a11y_data->dwell_timer =
1781+ clutter_threads_add_timeout (delay, trigger_dwell_click, device);
1782+
1783+ g_signal_emit_by_name (device->device_manager,
1784+ "ptr-a11y-timeout-started",
1785+ device,
1786+ CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
1787+ delay);
1788+}
1789+
1790+static void
1791+stop_dwell_timeout (ClutterInputDevice *device)
1792+{
1793+ if (device->ptr_a11y_data->dwell_timer)
1794+ {
1795+ g_source_remove (device->ptr_a11y_data->dwell_timer);
1796+ device->ptr_a11y_data->dwell_timer = 0;
1797+ device->ptr_a11y_data->dwell_gesture_started = FALSE;
1798+
1799+ g_signal_emit_by_name (device->device_manager,
1800+ "ptr-a11y-timeout-stopped",
1801+ device,
1802+ CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
1803+ }
1804+}
1805+
1806+static void
1807+update_dwell_position (ClutterInputDevice *device)
1808+{
1809+ device->ptr_a11y_data->dwell_x = device->ptr_a11y_data->current_x;
1810+ device->ptr_a11y_data->dwell_y = device->ptr_a11y_data->current_y;
1811+}
1812+
1813+static void
1814+update_current_position (ClutterInputDevice *device,
1815+ float x,
1816+ float y)
1817+{
1818+ device->ptr_a11y_data->current_x = x;
1819+ device->ptr_a11y_data->current_y = y;
1820+}
1821+
1822+static gboolean
1823+is_device_core_pointer (ClutterInputDevice *device)
1824+{
1825+ ClutterInputDevice *core_pointer;
1826+
1827+ core_pointer = clutter_device_manager_get_core_device (device->device_manager,
1828+ CLUTTER_POINTER_DEVICE);
1829+ if (core_pointer == NULL)
1830+ return FALSE;
1831+
1832+ return (core_pointer == device);
1833+}
1834+
1835+void
1836+_clutter_input_pointer_a11y_add_device (ClutterInputDevice *device)
1837+{
1838+ if (!is_device_core_pointer (device))
1839+ return;
1840+
1841+ device->accessibility_virtual_device =
1842+ clutter_device_manager_create_virtual_device (device->device_manager,
1843+ CLUTTER_POINTER_DEVICE);
1844+
1845+ device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1);
1846+}
1847+
1848+void
1849+_clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device)
1850+{
1851+ if (!is_device_core_pointer (device))
1852+ return;
1853+
1854+ /* Terminate a drag if started */
1855+ if (is_dwell_dragging (device))
1856+ emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
1857+
1858+ stop_dwell_timeout (device);
1859+ stop_secondary_click_timeout (device);
1860+
1861+ g_clear_pointer (&device->ptr_a11y_data, g_free);
1862+}
1863+
1864+void
1865+_clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
1866+ float x,
1867+ float y)
1868+{
1869+ if (!is_device_core_pointer (device))
1870+ return;
1871+
1872+ if (!_clutter_is_input_pointer_a11y_enabled (device))
1873+ return;
1874+
1875+ update_current_position (device, x, y);
1876+
1877+ if (is_secondary_click_enabled (device))
1878+ {
1879+ if (pointer_has_moved (device))
1880+ stop_secondary_click_timeout (device);
1881+ }
1882+
1883+ if (is_dwell_click_enabled (device))
1884+ {
1885+ if (should_stop_dwell (device))
1886+ stop_dwell_timeout (device);
1887+ else if (should_start_dwell (device))
1888+ start_dwell_timeout (device);
1889+ }
1890+
1891+ if (should_update_dwell_position (device))
1892+ update_dwell_position (device);
1893+}
1894+
1895+void
1896+_clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
1897+ int button,
1898+ gboolean pressed)
1899+{
1900+ if (!is_device_core_pointer (device))
1901+ return;
1902+
1903+ if (!_clutter_is_input_pointer_a11y_enabled (device))
1904+ return;
1905+
1906+ if (pressed)
1907+ {
1908+ device->ptr_a11y_data->n_btn_pressed++;
1909+
1910+ if (is_dwell_click_enabled (device))
1911+ stop_dwell_timeout (device);
1912+
1913+ if (is_dwell_dragging (device))
1914+ stop_dwell_timeout (device);
1915+
1916+ if (is_secondary_click_enabled (device))
1917+ {
1918+ if (button == CLUTTER_BUTTON_PRIMARY)
1919+ {
1920+ if (should_start_secondary_click_timeout (device))
1921+ start_secondary_click_timeout (device);
1922+ }
1923+ else if (is_secondary_click_pending (device))
1924+ {
1925+ stop_secondary_click_timeout (device);
1926+ }
1927+ }
1928+ }
1929+ else
1930+ {
1931+ if (has_button_pressed (device))
1932+ device->ptr_a11y_data->n_btn_pressed--;
1933+
1934+ if (is_secondary_click_triggered (device))
1935+ {
1936+ emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
1937+ stop_secondary_click_timeout (device);
1938+ }
1939+
1940+ if (is_secondary_click_pending (device))
1941+ stop_secondary_click_timeout (device);
1942+
1943+ if (is_dwell_dragging (device))
1944+ emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
1945+ }
1946+}
1947+
1948+gboolean
1949+_clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device)
1950+{
1951+ g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
1952+
1953+ return (is_secondary_click_enabled (device) || is_dwell_click_enabled (device));
1954+}
1955diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
1956index 71ec0d8..0fad6c6 100644
1957--- a/clutter/clutter/clutter-main.c
1958+++ b/clutter/clutter/clutter-main.c
1959@@ -58,6 +58,7 @@
1960 #include "clutter-device-manager-private.h"
1961 #include "clutter-event-private.h"
1962 #include "clutter-feature.h"
1963+#include "clutter-input-pointer-a11y-private.h"
1964 #include "clutter-main.h"
1965 #include "clutter-master-clock.h"
1966 #include "clutter-mutter.h"
1967@@ -84,8 +85,6 @@ G_LOCK_DEFINE_STATIC (ClutterCntx);
1968
1969 /* main lock and locking/unlocking functions */
1970 static GMutex clutter_threads_mutex;
1971-static GCallback clutter_threads_lock = NULL;
1972-static GCallback clutter_threads_unlock = NULL;
1973
1974 /* command line options */
1975 static gboolean clutter_is_initialized = FALSE;
1976@@ -145,38 +144,10 @@ static const GDebugKey clutter_paint_debug_keys[] = {
1977 { "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION },
1978 };
1979
1980-static void
1981-clutter_threads_impl_lock (void)
1982-{
1983- g_mutex_lock (&clutter_threads_mutex);
1984-}
1985-
1986-static void
1987-clutter_threads_impl_unlock (void)
1988-{
1989- /* we need to trylock here, in case the lock hasn't been acquired; on
1990- * various systems trying to release a mutex that hasn't been acquired
1991- * will cause a run-time error. trylock() will either fail, in which
1992- * case we can release the lock we own; or it will succeeds, in which
1993- * case we need to release the lock we just acquired. so we ignore the
1994- * returned value.
1995- *
1996- * see: https://bugs.gnome.org/679439
1997- */
1998- g_mutex_trylock (&clutter_threads_mutex);
1999- g_mutex_unlock (&clutter_threads_mutex);
2000-}
2001-
2002 static inline void
2003 clutter_threads_init_default (void)
2004 {
2005 g_mutex_init (&clutter_threads_mutex);
2006-
2007- if (clutter_threads_lock == NULL)
2008- clutter_threads_lock = clutter_threads_impl_lock;
2009-
2010- if (clutter_threads_unlock == NULL)
2011- clutter_threads_unlock = clutter_threads_impl_unlock;
2012 }
2013
2014 #define ENVIRONMENT_GROUP "Environment"
2015@@ -382,28 +353,6 @@ clutter_config_read (void)
2016 g_free (config_path);
2017 }
2018
2019-/**
2020- * clutter_get_show_fps:
2021- *
2022- * Returns whether Clutter should print out the frames per second on the
2023- * console. You can enable this setting either using the
2024- * <literal>CLUTTER_SHOW_FPS</literal> environment variable or passing
2025- * the <literal>--clutter-show-fps</literal> command line argument. *
2026- *
2027- * Return value: %TRUE if Clutter should show the FPS.
2028- *
2029- * Since: 0.4
2030- *
2031- * Deprecated: 1.10: This function does not do anything. Use the environment
2032- * variable or the configuration file to determine whether Clutter should
2033- * print out the FPS counter on the console.
2034- */
2035-gboolean
2036-clutter_get_show_fps (void)
2037-{
2038- return FALSE;
2039-}
2040-
2041 gboolean
2042 _clutter_context_get_show_fps (void)
2043 {
2044@@ -452,86 +401,6 @@ clutter_disable_accessibility (void)
2045 clutter_enable_accessibility = FALSE;
2046 }
2047
2048-/**
2049- * clutter_redraw:
2050- *
2051- * Forces a redraw of the entire stage. Applications should never use this
2052- * function, but queue a redraw using clutter_actor_queue_redraw().
2053- *
2054- * This function should only be used by libraries integrating Clutter from
2055- * within another toolkit.
2056- *
2057- * Deprecated: 1.10: Use clutter_stage_ensure_redraw() instead.
2058- */
2059-void
2060-clutter_redraw (ClutterStage *stage)
2061-{
2062- g_return_if_fail (CLUTTER_IS_STAGE (stage));
2063-
2064- clutter_stage_ensure_redraw (stage);
2065-}
2066-
2067-/**
2068- * clutter_set_motion_events_enabled:
2069- * @enable: %TRUE to enable per-actor motion events
2070- *
2071- * Sets whether per-actor motion events should be enabled or not on
2072- * all #ClutterStage<!-- -->s managed by Clutter.
2073- *
2074- * If @enable is %FALSE the following events will not work:
2075- *
2076- * - ClutterActor::motion-event, except on the #ClutterStage
2077- * - ClutterActor::enter-event
2078- * - ClutterActor::leave-event
2079- *
2080- * Since: 0.6
2081- *
2082- * Deprecated: 1.8: Use clutter_stage_set_motion_events_enabled() instead.
2083- */
2084-void
2085-clutter_set_motion_events_enabled (gboolean enable)
2086-{
2087- ClutterStageManager *stage_manager;
2088- ClutterMainContext *context;
2089- const GSList *l;
2090-
2091- enable = !!enable;
2092-
2093- context = _clutter_context_get_default ();
2094- if (context->motion_events_per_actor == enable)
2095- return;
2096-
2097- /* store the flag for later query and for newly created stages */
2098- context->motion_events_per_actor = enable;
2099-
2100- /* propagate the change to all stages */
2101- stage_manager = clutter_stage_manager_get_default ();
2102-
2103- for (l = clutter_stage_manager_peek_stages (stage_manager);
2104- l != NULL;
2105- l = l->next)
2106- {
2107- clutter_stage_set_motion_events_enabled (l->data, enable);
2108- }
2109-}
2110-
2111-/**
2112- * clutter_get_motion_events_enabled:
2113- *
2114- * Gets whether the per-actor motion events are enabled.
2115- *
2116- * Return value: %TRUE if the motion events are enabled
2117- *
2118- * Since: 0.6
2119- *
2120- * Deprecated: 1.8: Use clutter_stage_get_motion_events_enabled() instead.
2121- */
2122-gboolean
2123-clutter_get_motion_events_enabled (void)
2124-{
2125- return _clutter_context_get_motion_events_enabled ();
2126-}
2127-
2128 void
2129 _clutter_id_to_color (guint id_,
2130 ClutterColor *col)
2131@@ -783,69 +652,6 @@ clutter_main (void)
2132 clutter_main_loop_level--;
2133 }
2134
2135-/**
2136- * clutter_threads_init:
2137- *
2138- * Initialises the Clutter threading mechanism, so that Clutter API can be
2139- * called by multiple threads, using clutter_threads_enter() and
2140- * clutter_threads_leave() to mark the critical sections.
2141- *
2142- * You must call g_thread_init() before this function.
2143- *
2144- * This function must be called before clutter_init().
2145- *
2146- * It is safe to call this function multiple times.
2147- *
2148- * Since: 0.4
2149- *
2150- * Deprecated: 1.10: This function does not do anything. Threading support
2151- * is initialized when Clutter is initialized.
2152- */
2153-void
2154-clutter_threads_init (void)
2155-{
2156-}
2157-
2158-/**
2159- * clutter_threads_set_lock_functions: (skip)
2160- * @enter_fn: function called when aquiring the Clutter main lock
2161- * @leave_fn: function called when releasing the Clutter main lock
2162- *
2163- * Allows the application to replace the standard method that
2164- * Clutter uses to protect its data structures. Normally, Clutter
2165- * creates a single #GMutex that is locked by clutter_threads_enter(),
2166- * and released by clutter_threads_leave(); using this function an
2167- * application provides, instead, a function @enter_fn that is
2168- * called by clutter_threads_enter() and a function @leave_fn that is
2169- * called by clutter_threads_leave().
2170- *
2171- * The functions must provide at least same locking functionality
2172- * as the default implementation, but can also do extra application
2173- * specific processing.
2174- *
2175- * As an example, consider an application that has its own recursive
2176- * lock that when held, holds the Clutter lock as well. When Clutter
2177- * unlocks the Clutter lock when entering a recursive main loop, the
2178- * application must temporarily release its lock as well.
2179- *
2180- * Most threaded Clutter apps won't need to use this method.
2181- *
2182- * This method must be called before clutter_init(), and cannot
2183- * be called multiple times.
2184- *
2185- * Since: 0.4
2186- */
2187-void
2188-clutter_threads_set_lock_functions (GCallback enter_fn,
2189- GCallback leave_fn)
2190-{
2191- g_return_if_fail (clutter_threads_lock == NULL &&
2192- clutter_threads_unlock == NULL);
2193-
2194- clutter_threads_lock = enter_fn;
2195- clutter_threads_unlock = leave_fn;
2196-}
2197-
2198 gboolean
2199 _clutter_threads_dispatch (gpointer data)
2200 {
2201@@ -902,17 +708,11 @@ _clutter_threads_dispatch_free (gpointer data)
2202 * SafeClosure *closure = data;
2203 * gboolean res = FALSE;
2204 *
2205- * // mark the critical section //
2206- *
2207- * clutter_threads_enter();
2208- *
2209 * // the callback does not need to acquire the Clutter
2210 * / lock itself, as it is held by the this proxy handler
2211 * //
2212 * res = closure->callback (closure->data);
2213 *
2214- * clutter_threads_leave();
2215- *
2216 * return res;
2217 * }
2218 * static gulong
2219@@ -1092,69 +892,23 @@ clutter_threads_add_timeout (guint interval,
2220 void
2221 _clutter_threads_acquire_lock (void)
2222 {
2223- if (clutter_threads_lock != NULL)
2224- (* clutter_threads_lock) ();
2225+ g_mutex_lock (&clutter_threads_mutex);
2226 }
2227
2228 void
2229 _clutter_threads_release_lock (void)
2230 {
2231- if (clutter_threads_unlock != NULL)
2232- (* clutter_threads_unlock) ();
2233-}
2234-
2235-/**
2236- * clutter_threads_enter:
2237- *
2238- * Locks the Clutter thread lock.
2239- *
2240- * Since: 0.4
2241- *
2242- * Deprecated: 1.12: This function should not be used by application
2243- * code; marking critical sections is not portable on various
2244- * platforms. Instead of acquiring the Clutter lock, schedule UI
2245- * updates from the main loop using clutter_threads_add_idle() or
2246- * clutter_threads_add_timeout().
2247- */
2248-void
2249-clutter_threads_enter (void)
2250-{
2251- _clutter_threads_acquire_lock ();
2252-}
2253-
2254-/**
2255- * clutter_threads_leave:
2256- *
2257- * Unlocks the Clutter thread lock.
2258- *
2259- * Since: 0.4
2260- *
2261- * Deprecated: 1.12: This function should not be used by application
2262- * code; marking critical sections is not portable on various
2263- * platforms. Instead of acquiring the Clutter lock, schedule UI
2264- * updates from the main loop using clutter_threads_add_idle() or
2265- * clutter_threads_add_timeout().
2266- */
2267-void
2268-clutter_threads_leave (void)
2269-{
2270- _clutter_threads_release_lock ();
2271-}
2272-
2273-
2274-/**
2275- * clutter_get_debug_enabled:
2276- *
2277- * Check if Clutter has debugging enabled.
2278- *
2279- * Return value: %FALSE
2280- *
2281- * Deprecated: 1.10: This function does not do anything.
2282- */
2283-gboolean
2284-clutter_get_debug_enabled (void)
2285-{
2286- return FALSE;
2287+ /* we need to trylock here, in case the lock hasn't been acquired; on
2288+ * various systems trying to release a mutex that hasn't been acquired
2289+ * will cause a run-time error. trylock() will either fail, in which
2290+ * case we can release the lock we own; or it will succeeds, in which
2291+ * case we need to release the lock we just acquired. so we ignore the
2292+ * returned value.
2293+ *
2294+ * see: https://bugs.gnome.org/679439
2295+ */
2296+ g_mutex_trylock (&clutter_threads_mutex);
2297+ g_mutex_unlock (&clutter_threads_mutex);
2298 }
2299
2300 void
2301@@ -1204,7 +958,6 @@ clutter_context_get_default_unlocked (void)
2302 ctx->settings = clutter_settings_get_default ();
2303 _clutter_settings_set_backend (ctx->settings, ctx->backend);
2304
2305- ctx->motion_events_per_actor = TRUE;
2306 ctx->last_repaint_id = 1;
2307 }
2308
2309@@ -1225,36 +978,6 @@ _clutter_context_get_default (void)
2310 return retval;
2311 }
2312
2313-/**
2314- * clutter_get_timestamp:
2315- *
2316- * Returns the approximate number of microseconds passed since Clutter was
2317- * intialised.
2318- *
2319- * This function shdould not be used by application code.
2320- *
2321- * The output of this function depends on whether Clutter was configured to
2322- * enable its debugging code paths, so it's less useful than intended.
2323- *
2324- * Since Clutter 1.10, this function is an alias to g_get_monotonic_time()
2325- * if Clutter was configured to enable the debugging code paths.
2326- *
2327- * Return value: Number of microseconds since clutter_init() was called, or
2328- * zero if Clutter was not configured with debugging code paths.
2329- *
2330- * Deprecated: 1.10: Use #GTimer or g_get_monotonic_time() for a proper
2331- * timing source
2332- */
2333-gulong
2334-clutter_get_timestamp (void)
2335-{
2336-#ifdef CLUTTER_ENABLE_DEBUG
2337- return (gulong) g_get_monotonic_time ();
2338-#else
2339- return 0L;
2340-#endif
2341-}
2342-
2343 static gboolean
2344 clutter_arg_direction_cb (const char *key,
2345 const char *value,
2346@@ -2005,6 +1728,36 @@ emit_pointer_event (ClutterEvent *event,
2347 }
2348
2349 static inline void
2350+emit_crossing_event (ClutterEvent *event,
2351+ ClutterInputDevice *device)
2352+{
2353+ ClutterMainContext *context = _clutter_context_get_default ();
2354+ ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
2355+ ClutterActor *grab_actor = NULL;
2356+
2357+ if (_clutter_event_process_filters (event))
2358+ return;
2359+
2360+ if (sequence)
2361+ {
2362+ if (device->sequence_grab_actors != NULL)
2363+ grab_actor = g_hash_table_lookup (device->sequence_grab_actors, sequence);
2364+ }
2365+ else
2366+ {
2367+ if (context->pointer_grab_actor != NULL)
2368+ grab_actor = context->pointer_grab_actor;
2369+ else if (device != NULL && device->pointer_grab_actor != NULL)
2370+ grab_actor = device->pointer_grab_actor;
2371+ }
2372+
2373+ if (grab_actor != NULL)
2374+ clutter_actor_event (grab_actor, event, FALSE);
2375+ else
2376+ emit_event_chain (event);
2377+}
2378+
2379+static inline void
2380 emit_touch_event (ClutterEvent *event,
2381 ClutterInputDevice *device)
2382 {
2383@@ -2177,7 +1930,7 @@ _clutter_process_event_details (ClutterActor *stage,
2384 {
2385 ClutterActor *actor = NULL;
2386
2387- emit_pointer_event (event, device);
2388+ emit_crossing_event (event, device);
2389
2390 actor = _clutter_input_device_update (device, NULL, FALSE);
2391 if (actor != stage)
2392@@ -2189,12 +1942,12 @@ _clutter_process_event_details (ClutterActor *stage,
2393 crossing->crossing.related = stage;
2394 crossing->crossing.source = actor;
2395
2396- emit_pointer_event (crossing, device);
2397+ emit_crossing_event (crossing, device);
2398 clutter_event_free (crossing);
2399 }
2400 }
2401 else
2402- emit_pointer_event (event, device);
2403+ emit_crossing_event (event, device);
2404 break;
2405
2406 case CLUTTER_LEAVE:
2407@@ -2213,10 +1966,10 @@ _clutter_process_event_details (ClutterActor *stage,
2408 crossing->crossing.related = stage;
2409 crossing->crossing.source = device->cursor_actor;
2410
2411- emit_pointer_event (crossing, device);
2412+ emit_crossing_event (crossing, device);
2413 clutter_event_free (crossing);
2414 }
2415- emit_pointer_event (event, device);
2416+ emit_crossing_event (event, device);
2417 break;
2418
2419 case CLUTTER_DESTROY_NOTIFY:
2420@@ -2231,6 +1984,21 @@ _clutter_process_event_details (ClutterActor *stage,
2421 break;
2422
2423 case CLUTTER_MOTION:
2424+#ifdef CLUTTER_WINDOWING_X11
2425+ if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
2426+ {
2427+ if (_clutter_is_input_pointer_a11y_enabled (device))
2428+ {
2429+ ClutterInputDevice *core_pointer;
2430+ gfloat x, y;
2431+
2432+ clutter_event_get_coords (event, &x, &y);
2433+ core_pointer = clutter_device_manager_get_core_device (device->device_manager,
2434+ CLUTTER_POINTER_DEVICE);
2435+ _clutter_input_pointer_a11y_on_motion_event (core_pointer, x, y);
2436+ }
2437+ }
2438+#endif /* CLUTTER_WINDOWING_X11 */
2439 /* only the stage gets motion events if they are enabled */
2440 if (!clutter_stage_get_motion_events_enabled (CLUTTER_STAGE (stage)) &&
2441 event->any.source == NULL)
2442@@ -2269,6 +2037,22 @@ _clutter_process_event_details (ClutterActor *stage,
2443 /* fallthrough from motion */
2444 case CLUTTER_BUTTON_PRESS:
2445 case CLUTTER_BUTTON_RELEASE:
2446+#ifdef CLUTTER_WINDOWING_X11
2447+ if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
2448+ {
2449+ if (_clutter_is_input_pointer_a11y_enabled (device) && (event->type != CLUTTER_MOTION))
2450+ {
2451+ ClutterInputDevice *core_pointer;
2452+
2453+ core_pointer = clutter_device_manager_get_core_device (device->device_manager,
2454+ CLUTTER_POINTER_DEVICE);
2455+
2456+ _clutter_input_pointer_a11y_on_button_event (core_pointer,
2457+ event->button.button,
2458+ event->type == CLUTTER_BUTTON_PRESS);
2459+ }
2460+ }
2461+#endif /* CLUTTER_WINDOWING_X11 */
2462 case CLUTTER_SCROLL:
2463 case CLUTTER_TOUCHPAD_PINCH:
2464 case CLUTTER_TOUCHPAD_SWIPE:
2465@@ -2490,7 +2274,7 @@ _clutter_process_event_details (ClutterActor *stage,
2466 break;
2467
2468 case CLUTTER_STAGE_STATE:
2469- /* fullscreen / focus - forward to stage */
2470+ /* focus - forward to stage */
2471 event->any.source = stage;
2472 if (!_clutter_event_process_filters (event))
2473 clutter_stage_event (CLUTTER_STAGE (stage), event);
2474@@ -2596,24 +2380,6 @@ clutter_get_default_frame_rate (void)
2475 return context->frame_rate;
2476 }
2477
2478-/**
2479- * clutter_set_default_frame_rate:
2480- * @frames_per_sec: the new default frame rate
2481- *
2482- * Sets the default frame rate. This frame rate will be used to limit
2483- * the number of frames drawn if Clutter is not able to synchronize
2484- * with the vertical refresh rate of the display. When synchronization
2485- * is possible, this value is ignored.
2486- *
2487- * Since: 0.6
2488- *
2489- * Deprecated: 1.10: This function does not do anything any more.
2490- */
2491-void
2492-clutter_set_default_frame_rate (guint frames_per_sec)
2493-{
2494-}
2495-
2496 static void
2497 on_grab_actor_destroy (ClutterActor *actor,
2498 ClutterInputDevice *device)
2499@@ -2829,57 +2595,6 @@ clutter_input_device_get_grabbed_actor (ClutterInputDevice *device)
2500 }
2501
2502 /**
2503- * clutter_grab_pointer_for_device:
2504- * @actor: a #ClutterActor
2505- * @id_: a device id, or -1
2506- *
2507- * Grabs all the pointer events coming from the device @id for @actor.
2508- *
2509- * If @id is -1 then this function is equivalent to clutter_grab_pointer().
2510- *
2511- * Since: 0.8
2512- *
2513- * Deprecated: 1.10: Use clutter_input_device_grab() instead.
2514- */
2515-void
2516-clutter_grab_pointer_for_device (ClutterActor *actor,
2517- gint id_)
2518-{
2519- ClutterDeviceManager *manager;
2520- ClutterInputDevice *dev;
2521-
2522- g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
2523-
2524- /* essentially a global grab */
2525- if (id_ == -1)
2526- {
2527- if (actor == NULL)
2528- clutter_ungrab_pointer ();
2529- else
2530- clutter_grab_pointer (actor);
2531-
2532- return;
2533- }
2534-
2535- manager = clutter_device_manager_get_default ();
2536- if (manager == NULL)
2537- return;
2538-
2539- dev = clutter_device_manager_get_device (manager, id_);
2540- if (dev == NULL)
2541- return;
2542-
2543- if (dev->device_type != CLUTTER_POINTER_DEVICE)
2544- return;
2545-
2546- if (actor == NULL)
2547- clutter_input_device_ungrab (dev);
2548- else
2549- clutter_input_device_grab (dev, actor);
2550-}
2551-
2552-
2553-/**
2554 * clutter_ungrab_pointer:
2555 *
2556 * Removes an existing grab of the pointer.
2557@@ -2893,32 +2608,6 @@ clutter_ungrab_pointer (void)
2558 }
2559
2560 /**
2561- * clutter_ungrab_pointer_for_device:
2562- * @id_: a device id
2563- *
2564- * Removes an existing grab of the pointer events for device @id_.
2565- *
2566- * Since: 0.8
2567- *
2568- * Deprecated: 1.10: Use clutter_input_device_ungrab() instead.
2569- */
2570-void
2571-clutter_ungrab_pointer_for_device (gint id_)
2572-{
2573- ClutterDeviceManager *manager;
2574- ClutterInputDevice *device;
2575-
2576- manager = clutter_device_manager_get_default ();
2577- if (manager == NULL)
2578- return;
2579-
2580- device = clutter_device_manager_get_device (manager, id_);
2581- if (device != NULL)
2582- clutter_input_device_ungrab (device);
2583-}
2584-
2585-
2586-/**
2587 * clutter_get_pointer_grab:
2588 *
2589 * Queries the current pointer grab of clutter.
2590@@ -3018,170 +2707,6 @@ clutter_get_keyboard_grab (void)
2591 }
2592
2593 /**
2594- * clutter_clear_glyph_cache:
2595- *
2596- * Clears the internal cache of glyphs used by the Pango
2597- * renderer. This will free up some memory and GL texture
2598- * resources. The cache will be automatically refilled as more text is
2599- * drawn.
2600- *
2601- * Since: 0.8
2602- *
2603- * Deprecated: 1.10: Use clutter_get_font_map() and
2604- * cogl_pango_font_map_clear_glyph_cache() instead.
2605- */
2606-void
2607-clutter_clear_glyph_cache (void)
2608-{
2609- CoglPangoFontMap *font_map;
2610-
2611- font_map = clutter_context_get_pango_fontmap ();
2612- cogl_pango_font_map_clear_glyph_cache (font_map);
2613-}
2614-
2615-/**
2616- * clutter_set_font_flags:
2617- * @flags: The new flags
2618- *
2619- * Sets the font quality options for subsequent text rendering
2620- * operations.
2621- *
2622- * Using mipmapped textures will improve the quality for scaled down
2623- * text but will use more texture memory.
2624- *
2625- * Enabling hinting improves text quality for static text but may
2626- * introduce some artifacts if the text is animated.
2627- *
2628- * Since: 1.0
2629- *
2630- * Deprecated: 1.10: Use clutter_backend_set_font_options() and the
2631- * #cairo_font_option_t API.
2632- */
2633-void
2634-clutter_set_font_flags (ClutterFontFlags flags)
2635-{
2636- CoglPangoFontMap *font_map;
2637- ClutterFontFlags old_flags, changed_flags;
2638- const cairo_font_options_t *font_options;
2639- cairo_font_options_t *new_font_options;
2640- cairo_hint_style_t hint_style;
2641- gboolean use_mipmapping;
2642- ClutterBackend *backend;
2643-
2644- backend = clutter_get_default_backend ();
2645- font_map = clutter_context_get_pango_fontmap ();
2646- font_options = clutter_backend_get_font_options (backend);
2647- old_flags = 0;
2648-
2649- if (cogl_pango_font_map_get_use_mipmapping (font_map))
2650- old_flags |= CLUTTER_FONT_MIPMAPPING;
2651-
2652- hint_style = cairo_font_options_get_hint_style (font_options);
2653- if (hint_style != CAIRO_HINT_STYLE_DEFAULT &&
2654- hint_style != CAIRO_HINT_STYLE_NONE)
2655- old_flags |= CLUTTER_FONT_HINTING;
2656-
2657- if (old_flags == flags)
2658- return;
2659-
2660- new_font_options = cairo_font_options_copy (font_options);
2661-
2662- /* Only set the font options that have actually changed so we don't
2663- override a detailed setting from the backend */
2664- changed_flags = old_flags ^ flags;
2665-
2666- if ((changed_flags & CLUTTER_FONT_MIPMAPPING))
2667- {
2668- use_mipmapping = (changed_flags & CLUTTER_FONT_MIPMAPPING) != 0;
2669-
2670- cogl_pango_font_map_set_use_mipmapping (font_map, use_mipmapping);
2671- }
2672-
2673- if ((changed_flags & CLUTTER_FONT_HINTING))
2674- {
2675- hint_style = (flags & CLUTTER_FONT_HINTING)
2676- ? CAIRO_HINT_STYLE_FULL
2677- : CAIRO_HINT_STYLE_NONE;
2678-
2679- cairo_font_options_set_hint_style (new_font_options, hint_style);
2680- }
2681-
2682- clutter_backend_set_font_options (backend, new_font_options);
2683-
2684- cairo_font_options_destroy (new_font_options);
2685-}
2686-
2687-/**
2688- * clutter_get_font_flags:
2689- *
2690- * Gets the current font flags for rendering text. See
2691- * clutter_set_font_flags().
2692- *
2693- * Return value: The font flags
2694- *
2695- * Since: 1.0
2696- *
2697- * Deprecated: 1.10: Use clutter_backend_get_font_options() and the
2698- * #cairo_font_options_t API.
2699- */
2700-ClutterFontFlags
2701-clutter_get_font_flags (void)
2702-{
2703- CoglPangoFontMap *font_map = NULL;
2704- const cairo_font_options_t *font_options;
2705- ClutterFontFlags flags = 0;
2706- cairo_hint_style_t hint_style;
2707-
2708- font_map = clutter_context_get_pango_fontmap ();
2709- if (cogl_pango_font_map_get_use_mipmapping (font_map))
2710- flags |= CLUTTER_FONT_MIPMAPPING;
2711-
2712- font_options =
2713- clutter_backend_get_font_options (clutter_get_default_backend ());
2714-
2715- hint_style = cairo_font_options_get_hint_style (font_options);
2716- if (hint_style != CAIRO_HINT_STYLE_DEFAULT &&
2717- hint_style != CAIRO_HINT_STYLE_NONE)
2718- flags |= CLUTTER_FONT_HINTING;
2719-
2720- return flags;
2721-}
2722-
2723-/**
2724- * clutter_get_input_device_for_id:
2725- * @id_: the unique id for a device
2726- *
2727- * Retrieves the #ClutterInputDevice from its @id_. This is a convenience
2728- * wrapper for clutter_device_manager_get_device() and it is functionally
2729- * equivalent to:
2730- *
2731- * |[
2732- * ClutterDeviceManager *manager;
2733- * ClutterInputDevice *device;
2734- *
2735- * manager = clutter_device_manager_get_default ();
2736- * device = clutter_device_manager_get_device (manager, id);
2737- * ]|
2738- *
2739- * Return value: (transfer none): a #ClutterInputDevice, or %NULL
2740- *
2741- * Since: 0.8
2742- *
2743- * Deprecated: 1.10: Use clutter_device_manager_get_device() instead.
2744- */
2745-ClutterInputDevice *
2746-clutter_get_input_device_for_id (gint id_)
2747-{
2748- ClutterDeviceManager *manager;
2749-
2750- manager = clutter_device_manager_get_default ();
2751- if (manager == NULL)
2752- return NULL;
2753-
2754- return clutter_device_manager_get_device (manager, id_);
2755-}
2756-
2757-/**
2758 * clutter_get_font_map:
2759 *
2760 * Retrieves the #PangoFontMap instance used by Clutter.
2761@@ -3515,43 +3040,6 @@ _clutter_context_get_pick_mode (void)
2762 return context->pick_mode;
2763 }
2764
2765-void
2766-_clutter_context_push_shader_stack (ClutterActor *actor)
2767-{
2768- ClutterMainContext *context = _clutter_context_get_default ();
2769-
2770- context->shaders = g_slist_prepend (context->shaders, actor);
2771-}
2772-
2773-ClutterActor *
2774-_clutter_context_peek_shader_stack (void)
2775-{
2776- ClutterMainContext *context = _clutter_context_get_default ();
2777-
2778- if (context->shaders != NULL)
2779- return context->shaders->data;
2780-
2781- return NULL;
2782-}
2783-
2784-ClutterActor *
2785-_clutter_context_pop_shader_stack (ClutterActor *actor)
2786-{
2787- ClutterMainContext *context = _clutter_context_get_default ();
2788-
2789- context->shaders = g_slist_remove (context->shaders, actor);
2790-
2791- return _clutter_context_peek_shader_stack ();
2792-}
2793-
2794-gboolean
2795-_clutter_context_get_motion_events_enabled (void)
2796-{
2797- ClutterMainContext *context = _clutter_context_get_default ();
2798-
2799- return context->motion_events_per_actor;
2800-}
2801-
2802 /**
2803 * clutter_check_windowing_backend:
2804 * @backend_type: the name of the backend to check
2805diff --git a/clutter/clutter/clutter-main.h b/clutter/clutter/clutter-main.h
2806index 6bacc54..70e40f9 100644
2807--- a/clutter/clutter/clutter-main.h
2808+++ b/clutter/clutter/clutter-main.h
2809@@ -117,9 +117,6 @@ void clutter_disable_accessibility (void);
2810
2811 /* Threading functions */
2812 CLUTTER_EXPORT
2813-void clutter_threads_set_lock_functions (GCallback enter_fn,
2814- GCallback leave_fn);
2815-CLUTTER_EXPORT
2816 guint clutter_threads_add_idle (GSourceFunc func,
2817 gpointer data);
2818 CLUTTER_EXPORT
2819diff --git a/clutter/clutter/clutter-marshal.list b/clutter/clutter/clutter-marshal.list
2820index acf961e..749ea7c 100644
2821--- a/clutter/clutter/clutter-marshal.list
2822+++ b/clutter/clutter/clutter-marshal.list
2823@@ -23,6 +23,7 @@ VOID:FLOAT,FLOAT
2824 VOID:INT,INT,INT,INT
2825 VOID:OBJECT
2826 VOID:OBJECT,FLAGS
2827+VOID:OBJECT,FLAGS,UINT
2828 VOID:OBJECT,FLOAT,FLOAT
2829 VOID:OBJECT,FLOAT,FLOAT,FLAGS
2830 VOID:OBJECT,OBJECT
2831diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c
2832index 0647c3a..3197a32 100644
2833--- a/clutter/clutter/clutter-master-clock-default.c
2834+++ b/clutter/clutter/clutter-master-clock-default.c
2835@@ -64,9 +64,6 @@ struct _ClutterMasterClockDefault
2836 /* the current state of the clock, in usecs */
2837 gint64 cur_tick;
2838
2839- /* the previous state of the clock, in usecs, used to compute the delta */
2840- gint64 prev_tick;
2841-
2842 #ifdef CLUTTER_ENABLE_DEBUG
2843 gint64 frame_budget;
2844 gint64 remaining_budget;
2845@@ -77,12 +74,6 @@ struct _ClutterMasterClockDefault
2846 */
2847 GSource *source;
2848
2849- /* If the master clock is idle that means it has
2850- * fallen back to idle polling for timeline
2851- * progressions and it may have been some time since
2852- * the last real stage update.
2853- */
2854- guint idle : 1;
2855 guint ensure_next_iteration : 1;
2856
2857 guint paused : 1;
2858@@ -275,78 +266,12 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
2859 static gint
2860 master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock)
2861 {
2862- gint64 now, next;
2863- gint swap_delay;
2864-
2865 if (!master_clock_is_running (master_clock))
2866 return -1;
2867
2868 /* If all of the stages are busy waiting for a swap-buffers to complete
2869 * then we wait for one to be ready.. */
2870- swap_delay = master_clock_get_swap_wait_time (master_clock);
2871- if (swap_delay != 0)
2872- return swap_delay;
2873-
2874- /* When we have sync-to-vblank, we count on swap-buffer requests (or
2875- * swap-buffer-complete events if supported in the backend) to throttle our
2876- * frame rate so no additional delay is needed to start the next frame.
2877- *
2878- * If the master-clock has become idle due to no timeline progression causing
2879- * redraws then we can no longer rely on vblank synchronization because the
2880- * last real stage update/redraw may have happened a long time ago and so we
2881- * fallback to polling for timeline progressions every 1/frame_rate seconds.
2882- *
2883- * (NB: if there aren't even any timelines running then the master clock will
2884- * be completely stopped in master_clock_is_running())
2885- */
2886- if (clutter_feature_available (CLUTTER_FEATURE_SWAP_THROTTLE) &&
2887- !master_clock->idle)
2888- {
2889- CLUTTER_NOTE (SCHEDULER, "swap throttling available and updated stages");
2890- return 0;
2891- }
2892-
2893- if (master_clock->prev_tick == 0)
2894- {
2895- /* If we weren't previously running, then draw the next frame
2896- * immediately
2897- */
2898- CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
2899- return 0;
2900- }
2901-
2902- /* Otherwise, wait at least 1/frame_rate seconds since we last
2903- * started a frame
2904- */
2905- now = g_source_get_time (master_clock->source);
2906-
2907- next = master_clock->prev_tick;
2908-
2909- /* If time has gone backwards then there's no way of knowing how
2910- long we should wait so let's just dispatch immediately */
2911- if (now <= next)
2912- {
2913- CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");
2914-
2915- return 0;
2916- }
2917-
2918- next += (1000000L / clutter_get_default_frame_rate ());
2919-
2920- if (next <= now)
2921- {
2922- CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
2923- 1000000L / (gulong) clutter_get_default_frame_rate ());
2924-
2925- return 0;
2926- }
2927- else
2928- {
2929- CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
2930- (next - now) / 1000);
2931-
2932- return (next - now) / 1000;
2933- }
2934+ return master_clock_get_swap_wait_time (master_clock);
2935 }
2936
2937 static void
2938@@ -412,8 +337,7 @@ master_clock_advance_timelines (ClutterMasterClockDefault *master_clock)
2939 for (l = timelines; l != NULL; l = l->next)
2940 _clutter_timeline_do_tick (l->data, master_clock->cur_tick / 1000);
2941
2942- g_slist_foreach (timelines, (GFunc) g_object_unref, NULL);
2943- g_slist_free (timelines);
2944+ g_slist_free_full (timelines, g_object_unref);
2945
2946 #ifdef CLUTTER_ENABLE_DEBUG
2947 if (_clutter_diagnostic_enabled ())
2948@@ -531,7 +455,6 @@ clutter_clock_dispatch (GSource *source,
2949 {
2950 ClutterClockSource *clock_source = (ClutterClockSource *) source;
2951 ClutterMasterClockDefault *master_clock = clock_source->master_clock;
2952- gboolean stages_updated = FALSE;
2953 GSList *stages;
2954
2955 CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
2956@@ -551,8 +474,6 @@ clutter_clock_dispatch (GSource *source,
2957 */
2958 stages = master_clock_list_ready_stages (master_clock);
2959
2960- master_clock->idle = FALSE;
2961-
2962 /* Each frame is split into three separate phases: */
2963
2964 /* 1. process all the events; each stage goes through its events queue
2965@@ -565,19 +486,11 @@ clutter_clock_dispatch (GSource *source,
2966 master_clock_advance_timelines (master_clock);
2967
2968 /* 3. relayout and redraw the stages */
2969- stages_updated = master_clock_update_stages (master_clock, stages);
2970-
2971- /* The master clock goes idle if no stages were updated and falls back
2972- * to polling for timeline progressions... */
2973- if (!stages_updated)
2974- master_clock->idle = TRUE;
2975+ master_clock_update_stages (master_clock, stages);
2976
2977 master_clock_reschedule_stage_updates (master_clock, stages);
2978
2979- g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
2980- g_slist_free (stages);
2981-
2982- master_clock->prev_tick = master_clock->cur_tick;
2983+ g_slist_free_full (stages, g_object_unref);
2984
2985 _clutter_threads_release_lock ();
2986
2987@@ -610,7 +523,6 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self)
2988 source = clutter_clock_source_new (self);
2989 self->source = source;
2990
2991- self->idle = FALSE;
2992 self->ensure_next_iteration = FALSE;
2993 self->paused = FALSE;
2994
2995diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c
2996index d5efd58..41c3439 100644
2997--- a/clutter/clutter/clutter-paint-nodes.c
2998+++ b/clutter/clutter/clutter-paint-nodes.c
2999@@ -75,8 +75,7 @@ _clutter_paint_node_init_types (void)
3000 cogl_pipeline_set_color (default_color_pipeline, &cogl_color);
3001
3002 default_texture_pipeline = cogl_pipeline_new (ctx);
3003- cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0,
3004- COGL_TEXTURE_TYPE_2D);
3005+ cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0);
3006 cogl_pipeline_set_color (default_texture_pipeline, &cogl_color);
3007 cogl_pipeline_set_layer_wrap_mode (default_texture_pipeline, 0,
3008 COGL_PIPELINE_WRAP_MODE_AUTOMATIC);
3009diff --git a/clutter/clutter/clutter-path.c b/clutter/clutter/clutter-path.c
3010index 6ea433b..d80ddbe 100644
3011--- a/clutter/clutter/clutter-path.c
3012+++ b/clutter/clutter/clutter-path.c
3013@@ -295,8 +295,7 @@ clutter_path_clear (ClutterPath *path)
3014 {
3015 ClutterPathPrivate *priv = path->priv;
3016
3017- g_slist_foreach (priv->nodes, (GFunc) clutter_path_node_full_free, NULL);
3018- g_slist_free (priv->nodes);
3019+ g_slist_free_full (priv->nodes, (GDestroyNotify) clutter_path_node_full_free);
3020
3021 priv->nodes = priv->nodes_tail = NULL;
3022 priv->nodes_dirty = TRUE;
3023@@ -659,8 +658,7 @@ clutter_path_parse_description (const gchar *p,
3024 return TRUE;
3025
3026 fail:
3027- g_slist_foreach (nodes, (GFunc) clutter_path_node_full_free, NULL);
3028- g_slist_free (nodes);
3029+ g_slist_free_full (nodes, (GDestroyNotify) clutter_path_node_full_free);
3030 return FALSE;
3031 }
3032
3033diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h
3034index a5cd1fa..a97fd12 100644
3035--- a/clutter/clutter/clutter-private.h
3036+++ b/clutter/clutter/clutter-private.h
3037@@ -146,9 +146,6 @@ struct _ClutterMainContext
3038 ClutterActor *pointer_grab_actor;
3039 ClutterActor *keyboard_grab_actor;
3040
3041- /* stack of actors with shaders during paint */
3042- GSList *shaders;
3043-
3044 /* fb bit masks for col<->id mapping in picking */
3045 gint fb_r_mask;
3046 gint fb_g_mask;
3047@@ -173,7 +170,6 @@ struct _ClutterMainContext
3048
3049 /* boolean flags */
3050 guint is_initialized : 1;
3051- guint motion_events_per_actor : 1;
3052 guint defer_display_setup : 1;
3053 guint options_parsed : 1;
3054 guint show_fps : 1;
3055@@ -198,10 +194,6 @@ void _clutter_context_lock (void);
3056 void _clutter_context_unlock (void);
3057 gboolean _clutter_context_is_initialized (void);
3058 ClutterPickMode _clutter_context_get_pick_mode (void);
3059-void _clutter_context_push_shader_stack (ClutterActor *actor);
3060-ClutterActor * _clutter_context_pop_shader_stack (ClutterActor *actor);
3061-ClutterActor * _clutter_context_peek_shader_stack (void);
3062-gboolean _clutter_context_get_motion_events_enabled (void);
3063 gboolean _clutter_context_get_show_fps (void);
3064
3065 gboolean _clutter_feature_init (GError **error);
3066@@ -303,6 +295,11 @@ gboolean _clutter_util_matrix_decompose (const ClutterMatrix *src,
3067 ClutterVertex *translate_p,
3068 ClutterVertex4 *perspective_p);
3069
3070+PangoDirection _clutter_pango_unichar_direction (gunichar ch);
3071+
3072+PangoDirection _clutter_pango_find_base_dir (const gchar *text,
3073+ gint length);
3074+
3075 typedef struct _ClutterPlane
3076 {
3077 float v0[3];
3078diff --git a/clutter/clutter/clutter-script-parser.c b/clutter/clutter/clutter-script-parser.c
3079index 55e70da..b17a7d2 100644
3080--- a/clutter/clutter/clutter-script-parser.c
3081+++ b/clutter/clutter/clutter-script-parser.c
3082@@ -1636,14 +1636,17 @@ clutter_script_translate_parameters (ClutterScript *script,
3083 GObject *object,
3084 const gchar *name,
3085 GList *properties,
3086- GArray **params)
3087+ GPtrArray **param_names,
3088+ GArray **param_values)
3089 {
3090 ClutterScriptable *scriptable = NULL;
3091 ClutterScriptableIface *iface = NULL;
3092 GList *l, *unparsed;
3093 gboolean parse_custom = FALSE;
3094
3095- *params = g_array_new (FALSE, FALSE, sizeof (GParameter));
3096+ *param_names = g_ptr_array_new_with_free_func (g_free);
3097+ *param_values = g_array_new (FALSE, FALSE, sizeof (GValue));
3098+ g_array_set_clear_func (*param_values, (GDestroyNotify) g_value_unset);
3099
3100 if (CLUTTER_IS_SCRIPTABLE (object))
3101 {
3102@@ -1659,7 +1662,7 @@ clutter_script_translate_parameters (ClutterScript *script,
3103 for (l = properties; l != NULL; l = l->next)
3104 {
3105 PropertyInfo *pinfo = l->data;
3106- GParameter param = { NULL };
3107+ GValue value = G_VALUE_INIT;
3108 gboolean res = FALSE;
3109
3110 if (pinfo->is_child || pinfo->is_layout)
3111@@ -1676,12 +1679,12 @@ clutter_script_translate_parameters (ClutterScript *script,
3112 pinfo->name);
3113
3114 if (parse_custom)
3115- res = iface->parse_custom_node (scriptable, script, &param.value,
3116+ res = iface->parse_custom_node (scriptable, script, &value,
3117 pinfo->name,
3118 pinfo->node);
3119
3120 if (!res)
3121- res = _clutter_script_parse_node (script, &param.value,
3122+ res = _clutter_script_parse_node (script, &value,
3123 pinfo->name,
3124 pinfo->node,
3125 pinfo->pspec);
3126@@ -1693,9 +1696,8 @@ clutter_script_translate_parameters (ClutterScript *script,
3127 continue;
3128 }
3129
3130- param.name = g_strdup (pinfo->name);
3131-
3132- g_array_append_val (*params, param);
3133+ g_ptr_array_add (*param_names, g_strdup (pinfo->name));
3134+ g_array_append_val (*param_values, value);
3135
3136 property_info_free (pinfo);
3137 }
3138@@ -1710,7 +1712,8 @@ clutter_script_construct_parameters (ClutterScript *script,
3139 GType gtype,
3140 const gchar *name,
3141 GList *properties,
3142- GArray **construct_params)
3143+ GPtrArray **construct_param_names,
3144+ GArray **construct_param_values)
3145 {
3146 GObjectClass *klass;
3147 GList *l, *unparsed;
3148@@ -1718,14 +1721,17 @@ clutter_script_construct_parameters (ClutterScript *script,
3149 klass = g_type_class_ref (gtype);
3150 g_assert (klass != NULL);
3151
3152- *construct_params = g_array_new (FALSE, FALSE, sizeof (GParameter));
3153+ *construct_param_names = g_ptr_array_new_with_free_func (g_free);
3154+ *construct_param_values = g_array_new (FALSE, FALSE, sizeof (GValue));
3155+ g_array_set_clear_func (*construct_param_values,
3156+ (GDestroyNotify) g_value_unset);
3157
3158 unparsed = NULL;
3159
3160 for (l = properties; l != NULL; l = l->next)
3161 {
3162 PropertyInfo *pinfo = l->data;
3163- GParameter param = { NULL };
3164+ GValue value = G_VALUE_INIT;
3165 GParamSpec *pspec = NULL;
3166
3167 /* we allow custom property names for classes, so if we
3168@@ -1749,9 +1755,7 @@ clutter_script_construct_parameters (ClutterScript *script,
3169 continue;
3170 }
3171
3172- param.name = g_strdup (pinfo->name);
3173-
3174- if (!_clutter_script_parse_node (script, &param.value,
3175+ if (!_clutter_script_parse_node (script, &value,
3176 pinfo->name,
3177 pinfo->node,
3178 pinfo->pspec))
3179@@ -1760,7 +1764,8 @@ clutter_script_construct_parameters (ClutterScript *script,
3180 continue;
3181 }
3182
3183- g_array_append_val (*construct_params, param);
3184+ g_ptr_array_add (*construct_param_names, g_strdup (pinfo->name));
3185+ g_array_append_val (*construct_param_values, value);
3186
3187 property_info_free (pinfo);
3188 }
3189@@ -2021,8 +2026,7 @@ add_children (ClutterScript *script,
3190 clutter_container_add_actor (container, CLUTTER_ACTOR (object));
3191 }
3192
3193- g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
3194- g_list_free (oinfo->children);
3195+ g_list_free_full (oinfo->children, g_free);
3196
3197 oinfo->children = unresolved;
3198 }
3199@@ -2088,7 +2092,8 @@ _clutter_script_apply_properties (ClutterScript *script,
3200 gboolean set_custom_property = FALSE;
3201 GObject *object = oinfo->object;
3202 GList *properties;
3203- GArray *params;
3204+ g_autoptr (GPtrArray) param_names = NULL;
3205+ g_autoptr (GArray) param_values = NULL;
3206 guint i;
3207
3208 if (!oinfo->has_unresolved)
3209@@ -2112,34 +2117,31 @@ _clutter_script_apply_properties (ClutterScript *script,
3210 object,
3211 oinfo->id,
3212 properties,
3213- &params);
3214+ &param_names,
3215+ &param_values);
3216
3217 /* consume all the properties we could translate in this pass */
3218- for (i = 0; i < params->len; i++)
3219+ for (i = 0; i < param_names->len; i++)
3220 {
3221- GParameter *param = &g_array_index (params, GParameter, i);
3222+ char *name = g_ptr_array_index (param_names, i);
3223+ GValue *value = &g_array_index (param_values, GValue, i);
3224
3225 CLUTTER_NOTE (SCRIPT,
3226 "Setting %s property '%s' (type:%s) to object '%s' (id:%s)",
3227 set_custom_property ? "custom" : "regular",
3228- param->name,
3229- g_type_name (G_VALUE_TYPE (&param->value)),
3230+ name,
3231+ g_type_name (G_VALUE_TYPE (value)),
3232 g_type_name (oinfo->gtype),
3233 oinfo->id);
3234
3235 if (set_custom_property)
3236 iface->set_custom_property (scriptable, script,
3237- param->name,
3238- &param->value);
3239+ name,
3240+ value);
3241 else
3242- g_object_set_property (object, param->name, &param->value);
3243-
3244- g_free ((gchar *) param->name);
3245- g_value_unset (&param->value);
3246+ g_object_set_property (object, name, value);
3247 }
3248
3249- g_array_free (params, TRUE);
3250-
3251 _clutter_script_check_unresolved (script, oinfo);
3252 }
3253
3254@@ -2147,8 +2149,8 @@ void
3255 _clutter_script_construct_object (ClutterScript *script,
3256 ObjectInfo *oinfo)
3257 {
3258- GArray *params = NULL;
3259- guint i;
3260+ g_autoptr (GPtrArray) param_names = NULL;
3261+ g_autoptr (GArray) param_values = NULL;
3262
3263 /* we have completely updated the object */
3264 if (oinfo->object != NULL)
3265@@ -2191,25 +2193,14 @@ _clutter_script_construct_object (ClutterScript *script,
3266 oinfo->gtype,
3267 oinfo->id,
3268 properties,
3269- &params);
3270+ &param_names,
3271+ &param_values);
3272
3273 default_stage = clutter_stage_manager_get_default_stage (manager);
3274 oinfo->object = G_OBJECT (default_stage);
3275-
3276- for (i = 0; i < params->len; i++)
3277- {
3278- GParameter *param = &g_array_index (params, GParameter, i);
3279-
3280- g_free ((gchar *) param->name);
3281- g_value_unset (&param->value);
3282- }
3283-
3284- g_array_free (params, TRUE);
3285 }
3286 else
3287 {
3288- g_autoptr (GPtrArray) param_names = NULL;
3289- GArray *param_values;
3290 GList *properties = oinfo->properties;
3291
3292 /* every other object: first, we get the construction parameters */
3293@@ -2218,22 +2209,11 @@ _clutter_script_construct_object (ClutterScript *script,
3294 oinfo->gtype,
3295 oinfo->id,
3296 properties,
3297- &params);
3298-
3299- /* Convert GParameter → (GStrv, GValue[]) */
3300- param_names = g_ptr_array_sized_new (params->len);
3301- param_values = g_array_sized_new (TRUE, FALSE, sizeof (GValue), params->len);
3302- for (i = 0; i < params->len; i++)
3303- {
3304- GParameter *param = &g_array_index (params, GParameter, i);
3305-
3306- g_ptr_array_add (param_names, (gchar *) param->name);
3307- g_array_append_val (param_values, param->value);
3308- }
3309- g_ptr_array_add (param_names, NULL);
3310+ &param_names,
3311+ &param_values);
3312
3313 oinfo->object = g_object_new_with_properties (oinfo->gtype,
3314- params->len,
3315+ param_names->len,
3316 (const gchar **) param_names->pdata,
3317 (const GValue *) param_values->data);
3318
3319@@ -2242,17 +2222,6 @@ _clutter_script_construct_object (ClutterScript *script,
3320 * else too or only by this ClutterScript object.
3321 */
3322 g_object_ref_sink (oinfo->object);
3323-
3324- for (i = 0; i < params->len; i++)
3325- {
3326- GParameter *param = &g_array_index (params, GParameter, i);
3327-
3328- g_free ((gchar *) param->name);
3329- g_value_unset (&param->value);
3330- }
3331-
3332- g_array_free (param_values, FALSE);
3333- g_array_free (params, TRUE);
3334 }
3335
3336 g_assert (oinfo->object != NULL);
3337diff --git a/clutter/clutter/clutter-script.c b/clutter/clutter/clutter-script.c
3338index 7a58cd0..5914545 100644
3339--- a/clutter/clutter/clutter-script.c
3340+++ b/clutter/clutter/clutter-script.c
3341@@ -263,8 +263,6 @@ enum
3342
3343 static GParamSpec *obj_props[PROP_LAST];
3344
3345-#define CLUTTER_SCRIPT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_SCRIPT, ClutterScriptPrivate))
3346-
3347 struct _ClutterScriptPrivate
3348 {
3349 GHashTable *objects;
3350@@ -346,15 +344,12 @@ object_info_free (gpointer data)
3351 g_free (oinfo->class_name);
3352 g_free (oinfo->type_func);
3353
3354- g_list_foreach (oinfo->properties, (GFunc) property_info_free, NULL);
3355- g_list_free (oinfo->properties);
3356+ g_list_free_full (oinfo->properties, property_info_free);
3357
3358- g_list_foreach (oinfo->signals, (GFunc) signal_info_free, NULL);
3359- g_list_free (oinfo->signals);
3360+ g_list_free_full (oinfo->signals, signal_info_free);
3361
3362 /* these are ids */
3363- g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
3364- g_list_free (oinfo->children);
3365+ g_list_free_full (oinfo->children, g_free);
3366
3367 /* we unref top-level objects and leave the actors alone,
3368 * unless we are unmerging in which case we have to destroy
3369@@ -380,7 +375,7 @@ object_info_free (gpointer data)
3370 static void
3371 clutter_script_finalize (GObject *gobject)
3372 {
3373- ClutterScriptPrivate *priv = CLUTTER_SCRIPT_GET_PRIVATE (gobject);
3374+ ClutterScriptPrivate *priv = CLUTTER_SCRIPT (gobject)->priv;
3375
3376 g_object_unref (priv->parser);
3377 g_hash_table_destroy (priv->objects);
3378@@ -846,8 +841,7 @@ clutter_script_unmerge_objects (ClutterScript *script,
3379 for (l = data.ids; l != NULL; l = l->next)
3380 g_hash_table_remove (priv->objects, l->data);
3381
3382- g_slist_foreach (data.ids, (GFunc) g_free, NULL);
3383- g_slist_free (data.ids);
3384+ g_slist_free_full (data.ids, g_free);
3385
3386 clutter_script_ensure_objects (script);
3387 }
3388diff --git a/clutter/clutter/clutter-stage-manager.c b/clutter/clutter/clutter-stage-manager.c
3389index 7955a89..31b3a2b 100644
3390--- a/clutter/clutter/clutter-stage-manager.c
3391+++ b/clutter/clutter/clutter-stage-manager.c
3392@@ -89,8 +89,8 @@ clutter_stage_manager_dispose (GObject *gobject)
3393
3394 stage_manager = CLUTTER_STAGE_MANAGER (gobject);
3395
3396- g_slist_foreach (stage_manager->stages, (GFunc) clutter_actor_destroy, NULL);
3397- g_slist_free (stage_manager->stages);
3398+ g_slist_free_full (stage_manager->stages,
3399+ (GDestroyNotify) clutter_actor_destroy);
3400 stage_manager->stages = NULL;
3401
3402 G_OBJECT_CLASS (clutter_stage_manager_parent_class)->dispose (gobject);
3403diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
3404index 4799c29..b4255a4 100644
3405--- a/clutter/clutter/clutter-stage-private.h
3406+++ b/clutter/clutter/clutter-stage-private.h
3407@@ -40,6 +40,7 @@ void _clutter_stage_paint_view (ClutterStage
3408 ClutterStageView *view,
3409 const cairo_rectangle_int_t *clip);
3410
3411+void _clutter_stage_emit_after_paint (ClutterStage *stage);
3412 void _clutter_stage_set_window (ClutterStage *stage,
3413 ClutterStageWindow *stage_window);
3414 ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage);
3415@@ -117,7 +118,6 @@ void _clutter_stage_remove_touch_drag_actor (ClutterStage *st
3416
3417 ClutterStageState _clutter_stage_get_state (ClutterStage *stage);
3418 gboolean _clutter_stage_is_activated (ClutterStage *stage);
3419-gboolean _clutter_stage_is_fullscreen (ClutterStage *stage);
3420 gboolean _clutter_stage_update_state (ClutterStage *stage,
3421 ClutterStageState unset_state,
3422 ClutterStageState set_state);
3423diff --git a/clutter/clutter/clutter-stage-view-private.h b/clutter/clutter/clutter-stage-view-private.h
3424new file mode 100644
3425index 0000000..89c4259
3426--- /dev/null
3427+++ b/clutter/clutter/clutter-stage-view-private.h
3428@@ -0,0 +1,37 @@
3429+/*
3430+ * Copyright (C) 2019 Red Hat Inc.
3431+ *
3432+ * This library is free software; you can redistribute it and/or
3433+ * modify it under the terms of the GNU Lesser General Public
3434+ * License as published by the Free Software Foundation; either
3435+ * version 2 of the License, or (at your option) any later version.
3436+ *
3437+ * This library is distributed in the hope that it will be useful,
3438+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3439+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3440+ * Lesser General Public License for more details.
3441+ *
3442+ * You should have received a copy of the GNU Lesser General Public
3443+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
3444+ */
3445+
3446+#ifndef __CLUTTER_STAGE_VIEW_PRIVATE_H__
3447+#define __CLUTTER_STAGE_VIEW_PRIVATE_H__
3448+
3449+#include "clutter/clutter-stage-view.h"
3450+
3451+void clutter_stage_view_blit_offscreen (ClutterStageView *view,
3452+ const cairo_rectangle_int_t *clip);
3453+
3454+gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
3455+
3456+void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
3457+ gboolean dirty);
3458+
3459+gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
3460+
3461+void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
3462+ gboolean dirty);
3463+
3464+
3465+#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */
3466diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
3467index cd6cd35..a12261f 100644
3468--- a/clutter/clutter/clutter-stage-view.c
3469+++ b/clutter/clutter/clutter-stage-view.c
3470@@ -18,6 +18,7 @@
3471 #include "clutter-build-config.h"
3472
3473 #include "clutter/clutter-stage-view.h"
3474+#include "clutter/clutter-stage-view-private.h"
3475
3476 #include <cairo-gobject.h>
3477 #include <math.h>
3478@@ -61,6 +62,14 @@ clutter_stage_view_get_layout (ClutterStageView *view,
3479 *rect = priv->layout;
3480 }
3481
3482+/**
3483+ * clutter_stage_view_get_framebuffer:
3484+ * @view: a #ClutterStageView
3485+ *
3486+ * Retrieves the framebuffer of @view to draw to.
3487+ *
3488+ * Returns: (transfer none): a #CoglFramebuffer
3489+ */
3490 CoglFramebuffer *
3491 clutter_stage_view_get_framebuffer (ClutterStageView *view)
3492 {
3493@@ -73,6 +82,14 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view)
3494 return priv->framebuffer;
3495 }
3496
3497+/**
3498+ * clutter_stage_view_get_onscreen:
3499+ * @view: a #ClutterStageView
3500+ *
3501+ * Retrieves the onscreen framebuffer of @view if available.
3502+ *
3503+ * Returns: (transfer none): a #CoglFramebuffer
3504+ */
3505 CoglFramebuffer *
3506 clutter_stage_view_get_onscreen (ClutterStageView *view)
3507 {
3508diff --git a/clutter/clutter/clutter-stage-view.h b/clutter/clutter/clutter-stage-view.h
3509index 1264986..26bf10e 100644
3510--- a/clutter/clutter/clutter-stage-view.h
3511+++ b/clutter/clutter/clutter-stage-view.h
3512@@ -18,6 +18,10 @@
3513 #ifndef __CLUTTER_STAGE_VIEW_H__
3514 #define __CLUTTER_STAGE_VIEW_H__
3515
3516+#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
3517+#error "Only <clutter/clutter.h> can be included directly."
3518+#endif
3519+
3520 #include <cairo.h>
3521 #include <glib-object.h>
3522 #include <cogl/cogl.h>
3523@@ -57,22 +61,9 @@ void clutter_stage_view_transform_to_onscreen (ClutterStageView *vie
3524 gfloat *x,
3525 gfloat *y);
3526
3527-void clutter_stage_view_blit_offscreen (ClutterStageView *view,
3528- const cairo_rectangle_int_t *clip);
3529-
3530 CLUTTER_EXPORT
3531 float clutter_stage_view_get_scale (ClutterStageView *view);
3532
3533-gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
3534-
3535-void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
3536- gboolean dirty);
3537-
3538-gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
3539-
3540-void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
3541- gboolean dirty);
3542-
3543 CLUTTER_EXPORT
3544 void clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
3545 CoglMatrix *matrix);
3546diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c
3547index e8fa976..76421d6 100644
3548--- a/clutter/clutter/clutter-stage-window.c
3549+++ b/clutter/clutter/clutter-stage-window.c
3550@@ -63,16 +63,6 @@ _clutter_stage_window_set_title (ClutterStageWindow *window,
3551 }
3552
3553 void
3554-_clutter_stage_window_set_fullscreen (ClutterStageWindow *window,
3555- gboolean is_fullscreen)
3556-{
3557- ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
3558-
3559- if (iface->set_fullscreen)
3560- iface->set_fullscreen (window, is_fullscreen);
3561-}
3562-
3563-void
3564 _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
3565 gboolean is_visible)
3566 {
3567@@ -82,14 +72,6 @@ _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
3568 iface->set_cursor_visible (window, is_visible);
3569 }
3570
3571-void
3572-_clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
3573- gboolean is_resizable)
3574-{
3575- CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_user_resizable (window,
3576- is_resizable);
3577-}
3578-
3579 gboolean
3580 _clutter_stage_window_realize (ClutterStageWindow *window)
3581 {
3582diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h
3583index 6c36017..389ed05 100644
3584--- a/clutter/clutter/clutter-stage-window.h
3585+++ b/clutter/clutter/clutter-stage-window.h
3586@@ -30,12 +30,8 @@ struct _ClutterStageWindowInterface
3587
3588 void (* set_title) (ClutterStageWindow *stage_window,
3589 const gchar *title);
3590- void (* set_fullscreen) (ClutterStageWindow *stage_window,
3591- gboolean is_fullscreen);
3592 void (* set_cursor_visible) (ClutterStageWindow *stage_window,
3593 gboolean cursor_visible);
3594- void (* set_user_resizable) (ClutterStageWindow *stage_window,
3595- gboolean is_resizable);
3596
3597 gboolean (* realize) (ClutterStageWindow *stage_window);
3598 void (* unrealize) (ClutterStageWindow *stage_window);
3599@@ -83,12 +79,8 @@ ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *
3600
3601 void _clutter_stage_window_set_title (ClutterStageWindow *window,
3602 const gchar *title);
3603-void _clutter_stage_window_set_fullscreen (ClutterStageWindow *window,
3604- gboolean is_fullscreen);
3605 void _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
3606 gboolean is_visible);
3607-void _clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
3608- gboolean is_resizable);
3609
3610 gboolean _clutter_stage_window_realize (ClutterStageWindow *window);
3611 void _clutter_stage_window_unrealize (ClutterStageWindow *window);
3612diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
3613index 1eea5b3..3a4e56f 100644
3614--- a/clutter/clutter/clutter-stage.c
3615+++ b/clutter/clutter/clutter-stage.c
3616@@ -72,9 +72,11 @@
3617 #include "clutter-private.h"
3618 #include "clutter-stage-manager-private.h"
3619 #include "clutter-stage-private.h"
3620+#include "clutter-stage-view-private.h"
3621 #include "clutter-private.h"
3622
3623 #include "cogl/cogl.h"
3624+#include "cogl/cogl-trace.h"
3625
3626 /* <private>
3627 * ClutterStageHint:
3628@@ -147,13 +149,13 @@ struct _ClutterStagePrivate
3629 gpointer paint_data;
3630 GDestroyNotify paint_notify;
3631
3632+ cairo_rectangle_int_t view_clip;
3633+
3634 int update_freeze_count;
3635
3636 guint relayout_pending : 1;
3637 guint redraw_pending : 1;
3638- guint is_fullscreen : 1;
3639 guint is_cursor_visible : 1;
3640- guint is_user_resizable : 1;
3641 guint use_fog : 1;
3642 guint throttle_motion_events : 1;
3643 guint use_alpha : 1;
3644@@ -169,28 +171,27 @@ enum
3645 PROP_0,
3646
3647 PROP_COLOR,
3648- PROP_FULLSCREEN_SET,
3649- PROP_OFFSCREEN,
3650 PROP_CURSOR_VISIBLE,
3651 PROP_PERSPECTIVE,
3652 PROP_TITLE,
3653- PROP_USER_RESIZABLE,
3654 PROP_USE_FOG,
3655 PROP_FOG,
3656 PROP_USE_ALPHA,
3657 PROP_KEY_FOCUS,
3658 PROP_NO_CLEAR_HINT,
3659- PROP_ACCEPT_FOCUS
3660+ PROP_ACCEPT_FOCUS,
3661+ PROP_LAST
3662 };
3663
3664+static GParamSpec *obj_props[PROP_LAST] = { NULL, };
3665+
3666 enum
3667 {
3668- FULLSCREEN,
3669- UNFULLSCREEN,
3670 ACTIVATE,
3671 DEACTIVATE,
3672 DELETE_EVENT,
3673 AFTER_PAINT,
3674+ PAINT_VIEW,
3675 PRESENTED,
3676
3677 LAST_SIGNAL
3678@@ -403,40 +404,37 @@ clutter_stage_allocate (ClutterActor *self,
3679 flags | CLUTTER_DELEGATE_LAYOUT);
3680
3681 /* Ensure the window is sized correctly */
3682- if (!priv->is_fullscreen)
3683+ if (priv->min_size_changed)
3684 {
3685- if (priv->min_size_changed)
3686- {
3687- gfloat min_width, min_height;
3688- gboolean min_width_set, min_height_set;
3689-
3690- g_object_get (G_OBJECT (self),
3691- "min-width", &min_width,
3692- "min-width-set", &min_width_set,
3693- "min-height", &min_height,
3694- "min-height-set", &min_height_set,
3695- NULL);
3696-
3697- if (!min_width_set)
3698- min_width = 1;
3699- if (!min_height_set)
3700- min_height = 1;
3701-
3702- if (width < min_width)
3703- width = min_width;
3704- if (height < min_height)
3705- height = min_height;
3706-
3707- priv->min_size_changed = FALSE;
3708- }
3709+ gfloat min_width, min_height;
3710+ gboolean min_width_set, min_height_set;
3711+
3712+ g_object_get (G_OBJECT (self),
3713+ "min-width", &min_width,
3714+ "min-width-set", &min_width_set,
3715+ "min-height", &min_height,
3716+ "min-height-set", &min_height_set,
3717+ NULL);
3718+
3719+ if (!min_width_set)
3720+ min_width = 1;
3721+ if (!min_height_set)
3722+ min_height = 1;
3723+
3724+ if (width < min_width)
3725+ width = min_width;
3726+ if (height < min_height)
3727+ height = min_height;
3728+
3729+ priv->min_size_changed = FALSE;
3730+ }
3731
3732- if (window_size.width != CLUTTER_NEARBYINT (width) ||
3733- window_size.height != CLUTTER_NEARBYINT (height))
3734- {
3735- _clutter_stage_window_resize (priv->impl,
3736- CLUTTER_NEARBYINT (width),
3737- CLUTTER_NEARBYINT (height));
3738- }
3739+ if (window_size.width != CLUTTER_NEARBYINT (width) ||
3740+ window_size.height != CLUTTER_NEARBYINT (height))
3741+ {
3742+ _clutter_stage_window_resize (priv->impl,
3743+ CLUTTER_NEARBYINT (width),
3744+ CLUTTER_NEARBYINT (height));
3745 }
3746 }
3747 else
3748@@ -688,7 +686,22 @@ _clutter_stage_paint_view (ClutterStage *stage,
3749 if (!priv->impl)
3750 return;
3751
3752- clutter_stage_do_paint_view (stage, view, clip);
3753+ COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)");
3754+
3755+ priv->view_clip = *clip;
3756+
3757+ if (g_signal_has_handler_pending (stage, stage_signals[PAINT_VIEW],
3758+ 0, TRUE))
3759+ g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view);
3760+ else
3761+ CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view);
3762+
3763+ priv->view_clip = (cairo_rectangle_int_t) { 0 };
3764+}
3765+
3766+void
3767+_clutter_stage_emit_after_paint (ClutterStage *stage)
3768+{
3769 g_signal_emit (stage, stage_signals[AFTER_PAINT], 0);
3770 }
3771
3772@@ -829,7 +842,7 @@ clutter_stage_emit_key_focus_event (ClutterStage *stage,
3773 else
3774 g_signal_emit_by_name (priv->key_focused_actor, "key-focus-out");
3775
3776- g_object_notify (G_OBJECT (stage), "key-focus");
3777+ g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]);
3778 }
3779
3780 static void
3781@@ -844,40 +857,6 @@ clutter_stage_real_deactivate (ClutterStage *stage)
3782 clutter_stage_emit_key_focus_event (stage, FALSE);
3783 }
3784
3785-static void
3786-clutter_stage_real_fullscreen (ClutterStage *stage)
3787-{
3788- ClutterStagePrivate *priv = stage->priv;
3789- cairo_rectangle_int_t geom;
3790- ClutterActorBox box;
3791-
3792- /* we need to force an allocation here because the size
3793- * of the stage might have been changed by the backend
3794- *
3795- * this is a really bad solution to the issues caused by
3796- * the fact that fullscreening the stage on the X11 backends
3797- * is really an asynchronous operation
3798- */
3799- _clutter_stage_window_get_geometry (priv->impl, &geom);
3800-
3801- box.x1 = 0;
3802- box.y1 = 0;
3803- box.x2 = geom.width;
3804- box.y2 = geom.height;
3805-
3806- /* we need to blow the caching on the Stage size, given that
3807- * we're about to force an allocation, because if anything
3808- * ends up querying the size of the stage during the allocate()
3809- * call, like constraints or signal handlers, we'll get into an
3810- * inconsistent state: the stage will report the old cached size,
3811- * but the allocation will be updated anyway.
3812- */
3813- clutter_actor_set_size (CLUTTER_ACTOR (stage), -1.0, -1.0);
3814- clutter_actor_allocate (CLUTTER_ACTOR (stage),
3815- &box,
3816- CLUTTER_ALLOCATION_NONE);
3817-}
3818-
3819 void
3820 _clutter_stage_queue_event (ClutterStage *stage,
3821 ClutterEvent *event,
3822@@ -1225,22 +1204,31 @@ _clutter_stage_do_update (ClutterStage *stage)
3823 if (!CLUTTER_ACTOR_IS_REALIZED (stage))
3824 return FALSE;
3825
3826+ COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update");
3827+
3828 /* NB: We need to ensure we have an up to date layout *before* we
3829 * check or clear the pending redraws flag since a relayout may
3830 * queue a redraw.
3831 */
3832+ COGL_TRACE_BEGIN (ClutterStageRelayout, "Layout");
3833+
3834 _clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
3835
3836+ COGL_TRACE_END (ClutterStageRelayout);
3837+
3838 if (!priv->redraw_pending)
3839 return FALSE;
3840
3841 if (stage_was_relayout)
3842 pointers = _clutter_stage_check_updated_pointers (stage);
3843
3844- clutter_stage_maybe_finish_queue_redraws (stage);
3845+ COGL_TRACE_BEGIN (ClutterStagePaint, "Paint");
3846
3847+ clutter_stage_maybe_finish_queue_redraws (stage);
3848 clutter_stage_do_redraw (stage);
3849
3850+ COGL_TRACE_END (ClutterStagePaint);
3851+
3852 /* reset the guard, so that new redraws are possible */
3853 priv->redraw_pending = FALSE;
3854
3855@@ -1254,12 +1242,16 @@ _clutter_stage_do_update (ClutterStage *stage)
3856 }
3857 #endif /* CLUTTER_ENABLE_DEBUG */
3858
3859+ COGL_TRACE_BEGIN (ClutterStagePick, "Pick");
3860+
3861 while (pointers)
3862 {
3863 _clutter_input_device_update (pointers->data, NULL, TRUE);
3864 pointers = g_slist_delete_link (pointers, pointers);
3865 }
3866
3867+ COGL_TRACE_END (ClutterStagePick);
3868+
3869 return TRUE;
3870 }
3871
3872@@ -1303,14 +1295,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
3873 return TRUE;
3874
3875 if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
3876- {
3877- _clutter_stage_window_add_redraw_clip (stage_window, NULL);
3878- return FALSE;
3879- }
3880+ return FALSE;
3881
3882- /* Convert the clip volume into stage coordinates and then into an
3883- * axis aligned stage coordinates bounding box...
3884- */
3885 if (redraw_clip == NULL)
3886 {
3887 _clutter_stage_window_add_redraw_clip (stage_window, NULL);
3888@@ -1320,6 +1306,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
3889 if (redraw_clip->is_empty)
3890 return TRUE;
3891
3892+ /* Convert the clip volume into stage coordinates and then into an
3893+ * axis aligned stage coordinates bounding box... */
3894 _clutter_paint_volume_get_stage_paint_box (redraw_clip,
3895 stage,
3896 &bounding_box);
3897@@ -1574,10 +1562,13 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
3898 return retval;
3899 }
3900
3901-static ClutterStageView *
3902-get_view_at (ClutterStage *stage,
3903- int x,
3904- int y)
3905+/**
3906+ * clutter_stage_get_view_at: (skip)
3907+ */
3908+ClutterStageView *
3909+clutter_stage_get_view_at (ClutterStage *stage,
3910+ float x,
3911+ float y)
3912 {
3913 ClutterStagePrivate *priv = stage->priv;
3914 GList *l;
3915@@ -1624,7 +1615,7 @@ _clutter_stage_do_pick (ClutterStage *stage,
3916 if (x < 0 || x >= stage_width || y < 0 || y >= stage_height)
3917 return actor;
3918
3919- view = get_view_at (stage, x, y);
3920+ view = clutter_stage_get_view_at (stage, x, y);
3921 if (view)
3922 return _clutter_stage_do_pick_on_view (stage, x, y, mode, view);
3923
3924@@ -1703,11 +1694,6 @@ clutter_stage_set_property (GObject *object,
3925 clutter_value_get_color (value));
3926 break;
3927
3928- case PROP_OFFSCREEN:
3929- if (g_value_get_boolean (value))
3930- g_warning ("Offscreen stages are currently not supported\n");
3931- break;
3932-
3933 case PROP_CURSOR_VISIBLE:
3934 if (g_value_get_boolean (value))
3935 clutter_stage_show_cursor (stage);
3936@@ -1723,10 +1709,6 @@ clutter_stage_set_property (GObject *object,
3937 clutter_stage_set_title (stage, g_value_get_string (value));
3938 break;
3939
3940- case PROP_USER_RESIZABLE:
3941- clutter_stage_set_user_resizable (stage, g_value_get_boolean (value));
3942- break;
3943-
3944 case PROP_USE_FOG:
3945 clutter_stage_set_use_fog (stage, g_value_get_boolean (value));
3946 break;
3947@@ -1777,14 +1759,6 @@ clutter_stage_get_property (GObject *gobject,
3948 }
3949 break;
3950
3951- case PROP_OFFSCREEN:
3952- g_value_set_boolean (value, FALSE);
3953- break;
3954-
3955- case PROP_FULLSCREEN_SET:
3956- g_value_set_boolean (value, priv->is_fullscreen);
3957- break;
3958-
3959 case PROP_CURSOR_VISIBLE:
3960 g_value_set_boolean (value, priv->is_cursor_visible);
3961 break;
3962@@ -1797,10 +1771,6 @@ clutter_stage_get_property (GObject *gobject,
3963 g_value_set_string (value, priv->title);
3964 break;
3965
3966- case PROP_USER_RESIZABLE:
3967- g_value_set_boolean (value, priv->is_user_resizable);
3968- break;
3969-
3970 case PROP_USE_FOG:
3971 g_value_set_boolean (value, priv->use_fog);
3972 break;
3973@@ -1896,11 +1866,20 @@ clutter_stage_finalize (GObject *object)
3974 }
3975
3976 static void
3977+clutter_stage_real_paint_view (ClutterStage *stage,
3978+ ClutterStageView *view)
3979+{
3980+ ClutterStagePrivate *priv = stage->priv;
3981+ const cairo_rectangle_int_t *clip = &priv->view_clip;
3982+
3983+ clutter_stage_do_paint_view (stage, view, clip);
3984+}
3985+
3986+static void
3987 clutter_stage_class_init (ClutterStageClass *klass)
3988 {
3989 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3990 ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
3991- GParamSpec *pspec;
3992
3993 gobject_class->constructed = clutter_stage_constructed;
3994 gobject_class->set_property = clutter_stage_set_property;
3995@@ -1924,70 +1903,20 @@ clutter_stage_class_init (ClutterStageClass *klass)
3996 actor_class->queue_redraw = clutter_stage_real_queue_redraw;
3997 actor_class->apply_transform = clutter_stage_real_apply_transform;
3998
3999- /**
4000- * ClutterStage:fullscreen:
4001- *
4002- * Whether the stage should be fullscreen or not.
4003- *
4004- * This property is set by calling clutter_stage_set_fullscreen()
4005- * but since the actual implementation is delegated to the backend
4006- * you should connect to the notify::fullscreen-set signal in order
4007- * to get notification if the fullscreen state has been successfully
4008- * achieved.
4009- *
4010- * Since: 1.0
4011- */
4012- pspec = g_param_spec_boolean ("fullscreen-set",
4013- P_("Fullscreen Set"),
4014- P_("Whether the main stage is fullscreen"),
4015- FALSE,
4016- CLUTTER_PARAM_READABLE);
4017- g_object_class_install_property (gobject_class,
4018- PROP_FULLSCREEN_SET,
4019- pspec);
4020- /**
4021- * ClutterStage:offscreen:
4022- *
4023- * Whether the stage should be rendered in an offscreen buffer.
4024- *
4025- * Deprecated: 1.10: This property does not do anything.
4026- */
4027- pspec = g_param_spec_boolean ("offscreen",
4028- P_("Offscreen"),
4029- P_("Whether the main stage should be rendered offscreen"),
4030- FALSE,
4031- CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
4032- g_object_class_install_property (gobject_class,
4033- PROP_OFFSCREEN,
4034- pspec);
4035+ klass->paint_view = clutter_stage_real_paint_view;
4036+
4037 /**
4038 * ClutterStage:cursor-visible:
4039 *
4040 * Whether the mouse pointer should be visible
4041 */
4042- pspec = g_param_spec_boolean ("cursor-visible",
4043- P_("Cursor Visible"),
4044- P_("Whether the mouse pointer is visible on the main stage"),
4045- TRUE,
4046- CLUTTER_PARAM_READWRITE);
4047- g_object_class_install_property (gobject_class,
4048- PROP_CURSOR_VISIBLE,
4049- pspec);
4050- /**
4051- * ClutterStage:user-resizable:
4052- *
4053- * Whether the stage is resizable via user interaction.
4054- *
4055- * Since: 0.4
4056- */
4057- pspec = g_param_spec_boolean ("user-resizable",
4058- P_("User Resizable"),
4059- P_("Whether the stage is able to be resized via user interaction"),
4060- FALSE,
4061- CLUTTER_PARAM_READWRITE);
4062- g_object_class_install_property (gobject_class,
4063- PROP_USER_RESIZABLE,
4064- pspec);
4065+ obj_props[PROP_CURSOR_VISIBLE] =
4066+ g_param_spec_boolean ("cursor-visible",
4067+ P_("Cursor Visible"),
4068+ P_("Whether the mouse pointer is visible on the main stage"),
4069+ TRUE,
4070+ CLUTTER_PARAM_READWRITE);
4071+
4072 /**
4073 * ClutterStage:color:
4074 *
4075@@ -1996,13 +1925,13 @@ clutter_stage_class_init (ClutterStageClass *klass)
4076 * Deprecated: 1.10: Use the #ClutterActor:background-color property of
4077 * #ClutterActor instead.
4078 */
4079- pspec = clutter_param_spec_color ("color",
4080- P_("Color"),
4081- P_("The color of the stage"),
4082- &default_stage_color,
4083- CLUTTER_PARAM_READWRITE |
4084- G_PARAM_DEPRECATED);
4085- g_object_class_install_property (gobject_class, PROP_COLOR, pspec);
4086+ obj_props[PROP_COLOR] =
4087+ clutter_param_spec_color ("color",
4088+ P_("Color"),
4089+ P_("The color of the stage"),
4090+ &default_stage_color,
4091+ CLUTTER_PARAM_READWRITE |
4092+ G_PARAM_DEPRECATED);
4093
4094 /**
4095 * ClutterStage:perspective:
4096@@ -2012,14 +1941,12 @@ clutter_stage_class_init (ClutterStageClass *klass)
4097 *
4098 * Since: 0.8
4099 */
4100- pspec = g_param_spec_boxed ("perspective",
4101- P_("Perspective"),
4102- P_("Perspective projection parameters"),
4103- CLUTTER_TYPE_PERSPECTIVE,
4104- CLUTTER_PARAM_READWRITE);
4105- g_object_class_install_property (gobject_class,
4106- PROP_PERSPECTIVE,
4107- pspec);
4108+ obj_props[PROP_PERSPECTIVE] =
4109+ g_param_spec_boxed ("perspective",
4110+ P_("Perspective"),
4111+ P_("Perspective projection parameters"),
4112+ CLUTTER_TYPE_PERSPECTIVE,
4113+ CLUTTER_PARAM_READWRITE);
4114
4115 /**
4116 * ClutterStage:title:
4117@@ -2028,12 +1955,12 @@ clutter_stage_class_init (ClutterStageClass *klass)
4118 *
4119 * Since: 0.4
4120 */
4121- pspec = g_param_spec_string ("title",
4122- P_("Title"),
4123- P_("Stage Title"),
4124- NULL,
4125- CLUTTER_PARAM_READWRITE);
4126- g_object_class_install_property (gobject_class, PROP_TITLE, pspec);
4127+ obj_props[PROP_TITLE] =
4128+ g_param_spec_string ("title",
4129+ P_("Title"),
4130+ P_("Stage Title"),
4131+ NULL,
4132+ CLUTTER_PARAM_READWRITE);
4133
4134 /**
4135 * ClutterStage:use-fog:
4136@@ -2046,12 +1973,12 @@ clutter_stage_class_init (ClutterStageClass *klass)
4137 *
4138 * Deprecated: 1.10: This property does not do anything.
4139 */
4140- pspec = g_param_spec_boolean ("use-fog",
4141- P_("Use Fog"),
4142- P_("Whether to enable depth cueing"),
4143- FALSE,
4144- CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
4145- g_object_class_install_property (gobject_class, PROP_USE_FOG, pspec);
4146+ obj_props[PROP_USE_FOG] =
4147+ g_param_spec_boolean ("use-fog",
4148+ P_("Use Fog"),
4149+ P_("Whether to enable depth cueing"),
4150+ FALSE,
4151+ CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
4152
4153 /**
4154 * ClutterStage:fog:
4155@@ -2063,12 +1990,12 @@ clutter_stage_class_init (ClutterStageClass *klass)
4156 *
4157 * Deprecated: 1.10: This property does not do anything.
4158 */
4159- pspec = g_param_spec_boxed ("fog",
4160- P_("Fog"),
4161- P_("Settings for the depth cueing"),
4162- CLUTTER_TYPE_FOG,
4163- CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
4164- g_object_class_install_property (gobject_class, PROP_FOG, pspec);
4165+ obj_props[PROP_FOG] =
4166+ g_param_spec_boxed ("fog",
4167+ P_("Fog"),
4168+ P_("Settings for the depth cueing"),
4169+ CLUTTER_TYPE_FOG,
4170+ CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
4171
4172 /**
4173 * ClutterStage:use-alpha:
4174@@ -2080,12 +2007,12 @@ clutter_stage_class_init (ClutterStageClass *klass)
4175 *
4176 * Since: 1.2
4177 */
4178- pspec = g_param_spec_boolean ("use-alpha",
4179- P_("Use Alpha"),
4180- P_("Whether to honour the alpha component of the stage color"),
4181- FALSE,
4182- CLUTTER_PARAM_READWRITE);
4183- g_object_class_install_property (gobject_class, PROP_USE_ALPHA, pspec);
4184+ obj_props[PROP_USE_ALPHA] =
4185+ g_param_spec_boolean ("use-alpha",
4186+ P_("Use Alpha"),
4187+ P_("Whether to honour the alpha component of the stage color"),
4188+ FALSE,
4189+ CLUTTER_PARAM_READWRITE);
4190
4191 /**
4192 * ClutterStage:key-focus:
4193@@ -2097,12 +2024,12 @@ clutter_stage_class_init (ClutterStageClass *klass)
4194 *
4195 * Since: 1.2
4196 */
4197- pspec = g_param_spec_object ("key-focus",
4198- P_("Key Focus"),
4199- P_("The currently key focused actor"),
4200- CLUTTER_TYPE_ACTOR,
4201- CLUTTER_PARAM_READWRITE);
4202- g_object_class_install_property (gobject_class, PROP_KEY_FOCUS, pspec);
4203+ obj_props[PROP_KEY_FOCUS] =
4204+ g_param_spec_object ("key-focus",
4205+ P_("Key Focus"),
4206+ P_("The currently key focused actor"),
4207+ CLUTTER_TYPE_ACTOR,
4208+ CLUTTER_PARAM_READWRITE);
4209
4210 /**
4211 * ClutterStage:no-clear-hint:
4212@@ -2114,12 +2041,12 @@ clutter_stage_class_init (ClutterStageClass *klass)
4213 *
4214 * Since: 1.4
4215 */
4216- pspec = g_param_spec_boolean ("no-clear-hint",
4217- P_("No Clear Hint"),
4218- P_("Whether the stage should clear its contents"),
4219- FALSE,
4220- CLUTTER_PARAM_READWRITE);
4221- g_object_class_install_property (gobject_class, PROP_NO_CLEAR_HINT, pspec);
4222+ obj_props[PROP_NO_CLEAR_HINT] =
4223+ g_param_spec_boolean ("no-clear-hint",
4224+ P_("No Clear Hint"),
4225+ P_("Whether the stage should clear its contents"),
4226+ FALSE,
4227+ CLUTTER_PARAM_READWRITE);
4228
4229 /**
4230 * ClutterStage:accept-focus:
4231@@ -2128,46 +2055,15 @@ clutter_stage_class_init (ClutterStageClass *klass)
4232 *
4233 * Since: 1.6
4234 */
4235- pspec = g_param_spec_boolean ("accept-focus",
4236- P_("Accept Focus"),
4237- P_("Whether the stage should accept focus on show"),
4238- TRUE,
4239- CLUTTER_PARAM_READWRITE);
4240- g_object_class_install_property (gobject_class, PROP_ACCEPT_FOCUS, pspec);
4241+ obj_props[PROP_ACCEPT_FOCUS] =
4242+ g_param_spec_boolean ("accept-focus",
4243+ P_("Accept Focus"),
4244+ P_("Whether the stage should accept focus on show"),
4245+ TRUE,
4246+ CLUTTER_PARAM_READWRITE);
4247+
4248+ g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
4249
4250- /**
4251- * ClutterStage::fullscreen:
4252- * @stage: the stage which was fullscreened
4253- *
4254- * The ::fullscreen signal is emitted when the stage is made fullscreen.
4255- *
4256- * Since: 0.6
4257- */
4258- stage_signals[FULLSCREEN] =
4259- g_signal_new (I_("fullscreen"),
4260- G_TYPE_FROM_CLASS (gobject_class),
4261- G_SIGNAL_RUN_FIRST,
4262- G_STRUCT_OFFSET (ClutterStageClass, fullscreen),
4263- NULL, NULL,
4264- _clutter_marshal_VOID__VOID,
4265- G_TYPE_NONE, 0);
4266- /**
4267- * ClutterStage::unfullscreen:
4268- * @stage: the stage which has left a fullscreen state.
4269- *
4270- * The ::unfullscreen signal is emitted when the stage leaves a fullscreen
4271- * state.
4272- *
4273- * Since: 0.6
4274- */
4275- stage_signals[UNFULLSCREEN] =
4276- g_signal_new (I_("unfullscreen"),
4277- G_TYPE_FROM_CLASS (gobject_class),
4278- G_SIGNAL_RUN_LAST,
4279- G_STRUCT_OFFSET (ClutterStageClass, unfullscreen),
4280- NULL, NULL,
4281- _clutter_marshal_VOID__VOID,
4282- G_TYPE_NONE, 0);
4283 /**
4284 * ClutterStage::activate:
4285 * @stage: the stage which was activated
4286@@ -2252,6 +2148,28 @@ clutter_stage_class_init (ClutterStageClass *klass)
4287 G_TYPE_NONE, 0);
4288
4289 /**
4290+ * ClutterStage::paint-view:
4291+ * @stage: the stage that received the event
4292+ * @view: a #ClutterStageView
4293+ *
4294+ * The ::paint-view signal is emitted before a #ClutterStageView is being
4295+ * painted.
4296+ *
4297+ * The view is painted in the default handler. Hence, if you want to perform
4298+ * some action after the view is painted, like reading the contents of the
4299+ * framebuffer, use g_signal_connect_after() or pass %G_CONNECT_AFTER.
4300+ */
4301+ stage_signals[PAINT_VIEW] =
4302+ g_signal_new (I_("paint-view"),
4303+ G_TYPE_FROM_CLASS (gobject_class),
4304+ G_SIGNAL_RUN_LAST,
4305+ G_STRUCT_OFFSET (ClutterStageClass, paint_view),
4306+ NULL, NULL,
4307+ _clutter_marshal_VOID__OBJECT,
4308+ G_TYPE_NONE, 1,
4309+ CLUTTER_TYPE_STAGE_VIEW);
4310+
4311+ /**
4312 * ClutterStage::presented: (skip)
4313 * @stage: the stage that received the event
4314 * @frame_event: a #CoglFrameEvent
4315@@ -2268,7 +2186,6 @@ clutter_stage_class_init (ClutterStageClass *klass)
4316 G_TYPE_NONE, 2,
4317 G_TYPE_INT, G_TYPE_POINTER);
4318
4319- klass->fullscreen = clutter_stage_real_fullscreen;
4320 klass->activate = clutter_stage_real_activate;
4321 klass->deactivate = clutter_stage_real_deactivate;
4322 klass->delete_event = clutter_stage_real_delete_event;
4323@@ -2319,21 +2236,12 @@ clutter_stage_init (ClutterStage *self)
4324
4325 priv->event_queue = g_queue_new ();
4326
4327- priv->is_fullscreen = FALSE;
4328- priv->is_user_resizable = FALSE;
4329 priv->is_cursor_visible = TRUE;
4330 priv->use_fog = FALSE;
4331 priv->throttle_motion_events = TRUE;
4332 priv->min_size_changed = FALSE;
4333 priv->sync_delay = -1;
4334-
4335- /* XXX - we need to keep the invariant that calling
4336- * clutter_set_motion_event_enabled() before the stage creation
4337- * will cause motion event delivery to be disabled on any newly
4338- * created stage. this can go away when we break API and remove
4339- * deprecated functions.
4340- */
4341- priv->motion_events_enabled = _clutter_context_get_motion_events_enabled ();
4342+ priv->motion_events_enabled = TRUE;
4343
4344 clutter_actor_set_background_color (CLUTTER_ACTOR (self),
4345 &default_stage_color);
4346@@ -2452,7 +2360,7 @@ clutter_stage_set_color (ClutterStage *stage,
4347 {
4348 clutter_actor_set_background_color (CLUTTER_ACTOR (stage), color);
4349
4350- g_object_notify (G_OBJECT (stage), "color");
4351+ g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_COLOR]);
4352 }
4353
4354 /**
4355@@ -2717,136 +2625,6 @@ _clutter_stage_get_viewport (ClutterStage *stage,
4356 }
4357
4358 /**
4359- * clutter_stage_set_fullscreen:
4360- * @stage: a #ClutterStage
4361- * @fullscreen: %TRUE to to set the stage fullscreen
4362- *
4363- * Asks to place the stage window in the fullscreen or unfullscreen
4364- * states.
4365- *
4366- ( Note that you shouldn't assume the window is definitely full screen
4367- * afterward, because other entities (e.g. the user or window manager)
4368- * could unfullscreen it again, and not all window managers honor
4369- * requests to fullscreen windows.
4370- *
4371- * If you want to receive notification of the fullscreen state you
4372- * should either use the #ClutterStage::fullscreen and
4373- * #ClutterStage::unfullscreen signals, or use the notify signal
4374- * for the #ClutterStage:fullscreen-set property
4375- *
4376- * Since: 1.0
4377- */
4378-void
4379-clutter_stage_set_fullscreen (ClutterStage *stage,
4380- gboolean fullscreen)
4381-{
4382- ClutterStagePrivate *priv;
4383-
4384- g_return_if_fail (CLUTTER_IS_STAGE (stage));
4385-
4386- priv = stage->priv;
4387-
4388- if (priv->is_fullscreen != fullscreen)
4389- {
4390- ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
4391- ClutterStageWindowInterface *iface;
4392-
4393- iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
4394-
4395- /* Only set if backend implements.
4396- *
4397- * Also see clutter_stage_event() for setting priv->is_fullscreen
4398- * on state change event.
4399- */
4400- if (iface->set_fullscreen)
4401- iface->set_fullscreen (impl, fullscreen);
4402- }
4403-
4404- /* If the backend did fullscreen the stage window then we need to resize
4405- * the stage and update its viewport so we queue a relayout. Note: if the
4406- * fullscreen request is handled asynchronously we can't rely on this
4407- * queue_relayout to update the viewport, but for example the X backend
4408- * will recieve a ConfigureNotify after a successful resize which is how
4409- * we ensure the viewport is updated on X.
4410- */
4411- clutter_actor_queue_relayout (CLUTTER_ACTOR (stage));
4412-}
4413-
4414-/**
4415- * clutter_stage_get_fullscreen:
4416- * @stage: a #ClutterStage
4417- *
4418- * Retrieves whether the stage is full screen or not
4419- *
4420- * Return value: %TRUE if the stage is full screen
4421- *
4422- * Since: 1.0
4423- */
4424-gboolean
4425-clutter_stage_get_fullscreen (ClutterStage *stage)
4426-{
4427- g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
4428-
4429- return stage->priv->is_fullscreen;
4430-}
4431-
4432-/**
4433- * clutter_stage_set_user_resizable:
4434- * @stage: a #ClutterStage
4435- * @resizable: whether the stage should be user resizable.
4436- *
4437- * Sets if the stage is resizable by user interaction (e.g. via
4438- * window manager controls)
4439- *
4440- * Since: 0.4
4441- */
4442-void
4443-clutter_stage_set_user_resizable (ClutterStage *stage,
4444- gboolean resizable)
4445-{
4446- ClutterStagePrivate *priv;
4447-
4448- g_return_if_fail (CLUTTER_IS_STAGE (stage));
4449-
4450- priv = stage->priv;
4451-
4452- if (clutter_feature_available (CLUTTER_FEATURE_STAGE_USER_RESIZE)
4453- && priv->is_user_resizable != resizable)
4454- {
4455- ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl);
4456- ClutterStageWindowInterface *iface;
4457-
4458- iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl);
4459- if (iface->set_user_resizable)
4460- {
4461- priv->is_user_resizable = resizable;
4462-
4463- iface->set_user_resizable (impl, resizable);
4464-
4465- g_object_notify (G_OBJECT (stage), "user-resizable");
4466- }
4467- }
4468-}
4469-
4470-/**
4471- * clutter_stage_get_user_resizable:
4472- * @stage: a #ClutterStage
4473- *
4474- * Retrieves the value set with clutter_stage_set_user_resizable().
4475- *
4476- * Return value: %TRUE if the stage is resizable by the user.
4477- *
4478- * Since: 0.4
4479- */
4480-gboolean
4481-clutter_stage_get_user_resizable (ClutterStage *stage)
4482-{
4483- g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
4484-
4485- return stage->priv->is_user_resizable;
4486-}
4487-
4488-/**
4489 * clutter_stage_show_cursor:
4490 * @stage: a #ClutterStage
4491 *
4492@@ -2872,7 +2650,8 @@ clutter_stage_show_cursor (ClutterStage *stage)
4493
4494 iface->set_cursor_visible (impl, TRUE);
4495
4496- g_object_notify (G_OBJECT (stage), "cursor-visible");
4497+ g_object_notify_by_pspec (G_OBJECT (stage),
4498+ obj_props[PROP_CURSOR_VISIBLE]);
4499 }
4500 }
4501 }
4502@@ -2905,7 +2684,8 @@ clutter_stage_hide_cursor (ClutterStage *stage)
4503
4504 iface->set_cursor_visible (impl, FALSE);
4505
4506- g_object_notify (G_OBJECT (stage), "cursor-visible");
4507+ g_object_notify_by_pspec (G_OBJECT (stage),
4508+ obj_props[PROP_CURSOR_VISIBLE]);
4509 }
4510 }
4511 }
4512@@ -2949,6 +2729,8 @@ clutter_stage_read_pixels (ClutterStage *stage,
4513 float pixel_height;
4514 uint8_t *pixels;
4515
4516+ COGL_TRACE_BEGIN_SCOPED (ClutterStageReadPixels, "Read Pixels");
4517+
4518 g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
4519
4520 priv = stage->priv;
4521@@ -3014,7 +2796,11 @@ clutter_stage_read_pixels (ClutterStage *stage,
4522 * @y: Y coordinate to check
4523 *
4524 * Checks the scene at the coordinates @x and @y and returns a pointer
4525- * to the #ClutterActor at those coordinates.
4526+ * to the #ClutterActor at those coordinates. The result is the actor which
4527+ * would be at the specified location on the next redraw, and is not
4528+ * necessarily that which was there on the previous redraw. This allows the
4529+ * function to perform chronologically correctly after any queued changes to
4530+ * the scene, and even if nothing has been drawn.
4531 *
4532 * By using @pick_mode it is possible to control which actors will be
4533 * painted and thus available.
4534@@ -3051,13 +2837,9 @@ gboolean
4535 clutter_stage_event (ClutterStage *stage,
4536 ClutterEvent *event)
4537 {
4538- ClutterStagePrivate *priv;
4539-
4540 g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
4541 g_return_val_if_fail (event != NULL, FALSE);
4542
4543- priv = stage->priv;
4544-
4545 if (event->type == CLUTTER_DELETE)
4546 {
4547 gboolean retval = FALSE;
4548@@ -3077,24 +2859,6 @@ clutter_stage_event (ClutterStage *stage,
4549 if (clutter_actor_event (CLUTTER_ACTOR (stage), event, FALSE))
4550 return TRUE;
4551
4552- if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_FULLSCREEN)
4553- {
4554- if (event->stage_state.new_state & CLUTTER_STAGE_STATE_FULLSCREEN)
4555- {
4556- priv->is_fullscreen = TRUE;
4557- g_signal_emit (stage, stage_signals[FULLSCREEN], 0);
4558-
4559- g_object_notify (G_OBJECT (stage), "fullscreen-set");
4560- }
4561- else
4562- {
4563- priv->is_fullscreen = FALSE;
4564- g_signal_emit (stage, stage_signals[UNFULLSCREEN], 0);
4565-
4566- g_object_notify (G_OBJECT (stage), "fullscreen-set");
4567- }
4568- }
4569-
4570 if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_ACTIVATED)
4571 {
4572 if (event->stage_state.new_state & CLUTTER_STAGE_STATE_ACTIVATED)
4573@@ -3133,7 +2897,7 @@ clutter_stage_set_title (ClutterStage *stage,
4574 if (CLUTTER_STAGE_WINDOW_GET_IFACE(impl)->set_title != NULL)
4575 CLUTTER_STAGE_WINDOW_GET_IFACE (impl)->set_title (impl, priv->title);
4576
4577- g_object_notify (G_OBJECT (stage), "title");
4578+ g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_TITLE]);
4579 }
4580
4581 /**
4582@@ -3233,7 +2997,7 @@ clutter_stage_set_key_focus (ClutterStage *stage,
4583 else
4584 g_signal_emit_by_name (stage, "key-focus-in");
4585
4586- g_object_notify (G_OBJECT (stage), "key-focus");
4587+ g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]);
4588 }
4589
4590 /**
4591@@ -3911,7 +3675,7 @@ clutter_stage_set_use_alpha (ClutterStage *stage,
4592
4593 clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
4594
4595- g_object_notify (G_OBJECT (stage), "use-alpha");
4596+ g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_USE_ALPHA]);
4597 }
4598 }
4599
4600@@ -3949,8 +3713,6 @@ clutter_stage_get_use_alpha (ClutterStage *stage)
4601 * If the current size of @stage is smaller than the minimum size, the
4602 * @stage will be resized to the new @width and @height
4603 *
4604- * This function has no effect if @stage is fullscreen
4605- *
4606 * Since: 1.2
4607 */
4608 void
4609@@ -4127,7 +3889,7 @@ clutter_stage_set_no_clear_hint (ClutterStage *stage,
4610
4611 priv->stage_hints = new_hints;
4612
4613- g_object_notify (G_OBJECT (stage), "no-clear-hint");
4614+ g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_NO_CLEAR_HINT]);
4615 }
4616
4617 /**
4618@@ -4369,7 +4131,7 @@ clutter_stage_set_accept_focus (ClutterStage *stage,
4619 if (priv->accept_focus != accept_focus)
4620 {
4621 _clutter_stage_window_set_accept_focus (priv->impl, accept_focus);
4622- g_object_notify (G_OBJECT (stage), "accept-focus");
4623+ g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_ACCEPT_FOCUS]);
4624 }
4625 }
4626
4627@@ -4638,20 +4400,6 @@ _clutter_stage_is_activated (ClutterStage *stage)
4628 }
4629
4630 /*< private >
4631- * _clutter_stage_is_fullscreen:
4632- * @stage: a #ClutterStage
4633- *
4634- * Checks whether the @stage state includes %CLUTTER_STAGE_STATE_FULLSCREEN.
4635- *
4636- * Return value: %TRUE if the @stage is fullscreen
4637- */
4638-gboolean
4639-_clutter_stage_is_fullscreen (ClutterStage *stage)
4640-{
4641- return (stage->priv->current_state & CLUTTER_STAGE_STATE_FULLSCREEN) != 0;
4642-}
4643-
4644-/*< private >
4645 * _clutter_stage_update_state:
4646 * @stage: a #ClutterStage
4647 * @unset_flags: flags to unset
4648diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h
4649index 5730af7..c28904b 100644
4650--- a/clutter/clutter/clutter-stage.h
4651+++ b/clutter/clutter/clutter-stage.h
4652@@ -30,6 +30,7 @@
4653
4654 #include <clutter/clutter-types.h>
4655 #include <clutter/clutter-group.h>
4656+#include <clutter/clutter-stage-view.h>
4657
4658 G_BEGIN_DECLS
4659
4660@@ -61,8 +62,6 @@ struct _ClutterStage
4661 };
4662 /**
4663 * ClutterStageClass:
4664- * @fullscreen: handler for the #ClutterStage::fullscreen signal
4665- * @unfullscreen: handler for the #ClutterStage::unfullscreen signal
4666 * @activate: handler for the #ClutterStage::activate signal
4667 * @deactivate: handler for the #ClutterStage::deactivate signal
4668 * @delete_event: handler for the #ClutterStage::delete-event signal
4669@@ -79,17 +78,18 @@ struct _ClutterStageClass
4670
4671 /*< public >*/
4672 /* signals */
4673- void (* fullscreen) (ClutterStage *stage);
4674- void (* unfullscreen) (ClutterStage *stage);
4675 void (* activate) (ClutterStage *stage);
4676 void (* deactivate) (ClutterStage *stage);
4677
4678 gboolean (* delete_event) (ClutterStage *stage,
4679 ClutterEvent *event);
4680
4681+ void (* paint_view) (ClutterStage *stage,
4682+ ClutterStageView *view);
4683+
4684 /*< private >*/
4685 /* padding for future expansion */
4686- gpointer _padding_dummy[31];
4687+ gpointer _padding_dummy[30];
4688 };
4689
4690 /**
4691@@ -168,11 +168,6 @@ CLUTTER_EXPORT
4692 void clutter_stage_get_perspective (ClutterStage *stage,
4693 ClutterPerspective *perspective);
4694 CLUTTER_EXPORT
4695-void clutter_stage_set_fullscreen (ClutterStage *stage,
4696- gboolean fullscreen);
4697-CLUTTER_EXPORT
4698-gboolean clutter_stage_get_fullscreen (ClutterStage *stage);
4699-CLUTTER_EXPORT
4700 void clutter_stage_show_cursor (ClutterStage *stage);
4701 CLUTTER_EXPORT
4702 void clutter_stage_hide_cursor (ClutterStage *stage);
4703@@ -181,11 +176,6 @@ void clutter_stage_set_title (ClutterStage
4704 const gchar *title);
4705 CLUTTER_EXPORT
4706 const gchar * clutter_stage_get_title (ClutterStage *stage);
4707-CLUTTER_EXPORT
4708-void clutter_stage_set_user_resizable (ClutterStage *stage,
4709- gboolean resizable);
4710-CLUTTER_EXPORT
4711-gboolean clutter_stage_get_user_resizable (ClutterStage *stage);
4712
4713 CLUTTER_EXPORT
4714 void clutter_stage_set_minimum_size (ClutterStage *stage,
4715@@ -274,6 +264,10 @@ gboolean clutter_stage_capture (ClutterStage *stage,
4716 cairo_rectangle_int_t *rect,
4717 ClutterCapture **captures,
4718 int *n_captures);
4719+CLUTTER_EXPORT
4720+ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage,
4721+ float x,
4722+ float y);
4723
4724 G_END_DECLS
4725
4726diff --git a/clutter/clutter/clutter-text-buffer.c b/clutter/clutter/clutter-text-buffer.c
4727index f3a40d6..1436921 100644
4728--- a/clutter/clutter/clutter-text-buffer.c
4729+++ b/clutter/clutter/clutter-text-buffer.c
4730@@ -171,7 +171,7 @@ clutter_text_buffer_normal_insert_text (ClutterTextBuffer *buffer,
4731
4732 /* Actual text insertion */
4733 at = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text;
4734- g_memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at);
4735+ memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at);
4736 memcpy (pv->normal_text + at, chars, n_bytes);
4737
4738 /* Book keeping */
4739@@ -201,7 +201,7 @@ clutter_text_buffer_normal_delete_text (ClutterTextBuffer *buffer,
4740 start = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text;
4741 end = g_utf8_offset_to_pointer (pv->normal_text, position + n_chars) - pv->normal_text;
4742
4743- g_memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end);
4744+ memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end);
4745 pv->normal_text_chars -= n_chars;
4746 pv->normal_text_bytes -= (end - start);
4747
4748@@ -228,8 +228,8 @@ clutter_text_buffer_real_inserted_text (ClutterTextBuffer *buffer,
4749 const gchar *chars,
4750 guint n_chars)
4751 {
4752- g_object_notify (G_OBJECT (buffer), "text");
4753- g_object_notify (G_OBJECT (buffer), "length");
4754+ g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]);
4755+ g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]);
4756 }
4757
4758 static void
4759@@ -237,8 +237,8 @@ clutter_text_buffer_real_deleted_text (ClutterTextBuffer *buffer,
4760 guint position,
4761 guint n_chars)
4762 {
4763- g_object_notify (G_OBJECT (buffer), "text");
4764- g_object_notify (G_OBJECT (buffer), "length");
4765+ g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]);
4766+ g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]);
4767 }
4768
4769 /* --------------------------------------------------------------------------------
4770@@ -598,7 +598,7 @@ clutter_text_buffer_set_max_length (ClutterTextBuffer *buffer,
4771 clutter_text_buffer_delete_text (buffer, max_length, -1);
4772
4773 buffer->priv->max_length = max_length;
4774- g_object_notify (G_OBJECT (buffer), "max-length");
4775+ g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_MAX_LENGTH]);
4776 }
4777
4778 /**
4779diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c
4780index 000bbbb..7bc6565 100644
4781--- a/clutter/clutter/clutter-text.c
4782+++ b/clutter/clutter/clutter-text.c
4783@@ -751,7 +751,7 @@ clutter_text_create_layout_no_cache (ClutterText *text,
4784 if (priv->password_char != 0)
4785 pango_dir = PANGO_DIRECTION_NEUTRAL;
4786 else
4787- pango_dir = pango_find_base_dir (contents, contents_len);
4788+ pango_dir = _clutter_pango_find_base_dir (contents, contents_len);
4789
4790 if (pango_dir == PANGO_DIRECTION_NEUTRAL)
4791 {
4792@@ -4821,7 +4821,7 @@ buffer_notify_max_length (ClutterTextBuffer *buffer,
4793 GParamSpec *spec,
4794 ClutterText *self)
4795 {
4796- g_object_notify (G_OBJECT (self), "max-length");
4797+ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAX_LENGTH]);
4798 }
4799
4800 static void
4801@@ -4920,9 +4920,9 @@ clutter_text_set_buffer (ClutterText *self,
4802
4803 obj = G_OBJECT (self);
4804 g_object_freeze_notify (obj);
4805- g_object_notify (obj, "buffer");
4806- g_object_notify (obj, "text");
4807- g_object_notify (obj, "max-length");
4808+ g_object_notify_by_pspec (obj, obj_props[PROP_BUFFER]);
4809+ g_object_notify_by_pspec (obj, obj_props[PROP_TEXT]);
4810+ g_object_notify_by_pspec (obj, obj_props[PROP_MAX_LENGTH]);
4811 g_object_thaw_notify (obj);
4812 }
4813
4814diff --git a/clutter/clutter/clutter-util.c b/clutter/clutter/clutter-util.c
4815index ed52b69..917da76 100644
4816--- a/clutter/clutter/clutter-util.c
4817+++ b/clutter/clutter/clutter-util.c
4818@@ -32,6 +32,7 @@
4819
4820 #include "clutter-build-config.h"
4821
4822+#include <fribidi.h>
4823 #include <math.h>
4824
4825 #include "clutter-debug.h"
4826@@ -105,8 +106,9 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview,
4827 }
4828 }
4829
4830-void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
4831- ClutterRect *dest)
4832+void
4833+_clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
4834+ ClutterRect *dest)
4835 {
4836 *dest = (ClutterRect) {
4837 .origin = {
4838@@ -120,8 +122,9 @@ void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
4839 };
4840 }
4841
4842-void _clutter_util_rectangle_int_extents (const ClutterRect *src,
4843- cairo_rectangle_int_t *dest)
4844+void
4845+_clutter_util_rectangle_int_extents (const ClutterRect *src,
4846+ cairo_rectangle_int_t *dest)
4847 {
4848 ClutterRect tmp = *src;
4849
4850@@ -135,10 +138,11 @@ void _clutter_util_rectangle_int_extents (const ClutterRect *src,
4851 };
4852 }
4853
4854-void _clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
4855- int x,
4856- int y,
4857- cairo_rectangle_int_t *dest)
4858+void
4859+_clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
4860+ int x,
4861+ int y,
4862+ cairo_rectangle_int_t *dest)
4863 {
4864 *dest = *src;
4865
4866@@ -696,3 +700,45 @@ clutter_interval_register_progress_func (GType value_type,
4867
4868 G_UNLOCK (progress_funcs);
4869 }
4870+
4871+PangoDirection
4872+_clutter_pango_unichar_direction (gunichar ch)
4873+{
4874+ FriBidiCharType fribidi_ch_type;
4875+
4876+ G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar));
4877+
4878+ fribidi_ch_type = fribidi_get_bidi_type (ch);
4879+
4880+ if (!FRIBIDI_IS_STRONG (fribidi_ch_type))
4881+ return PANGO_DIRECTION_NEUTRAL;
4882+ else if (FRIBIDI_IS_RTL (fribidi_ch_type))
4883+ return PANGO_DIRECTION_RTL;
4884+ else
4885+ return PANGO_DIRECTION_LTR;
4886+}
4887+
4888+PangoDirection
4889+_clutter_pango_find_base_dir (const gchar *text,
4890+ gint length)
4891+{
4892+ PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
4893+ const gchar *p;
4894+
4895+ g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL);
4896+
4897+ p = text;
4898+ while ((length < 0 || p < text + length) && *p)
4899+ {
4900+ gunichar wc = g_utf8_get_char (p);
4901+
4902+ dir = _clutter_pango_unichar_direction (wc);
4903+
4904+ if (dir != PANGO_DIRECTION_NEUTRAL)
4905+ break;
4906+
4907+ p = g_utf8_next_char (p);
4908+ }
4909+
4910+ return dir;
4911+}
4912diff --git a/clutter/clutter/clutter.h b/clutter/clutter/clutter.h
4913index 231d8cd..ec84691 100644
4914--- a/clutter/clutter/clutter.h
4915+++ b/clutter/clutter/clutter.h
4916@@ -101,6 +101,7 @@
4917 #include "clutter-snap-constraint.h"
4918 #include "clutter-stage.h"
4919 #include "clutter-stage-manager.h"
4920+#include "clutter-stage-view.h"
4921 #include "clutter-tap-action.h"
4922 #include "clutter-test-utils.h"
4923 #include "clutter-texture.h"
4924diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
4925index e0c3918..8f97a5f 100644
4926--- a/clutter/clutter/cogl/clutter-stage-cogl.c
4927+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
4928@@ -45,6 +45,9 @@
4929 #include "clutter-main.h"
4930 #include "clutter-private.h"
4931 #include "clutter-stage-private.h"
4932+#include "clutter-stage-view-private.h"
4933+
4934+#include "cogl/cogl-trace.h"
4935
4936 typedef struct _ClutterStageViewCoglPrivate
4937 {
4938@@ -78,6 +81,10 @@ enum
4939 };
4940
4941 static void
4942+clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
4943+ gint sync_delay);
4944+
4945+static void
4946 clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
4947 {
4948 CLUTTER_NOTE (BACKEND, "Unrealizing Cogl stage [%p]", stage_window);
4949@@ -122,6 +129,16 @@ _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
4950 }
4951
4952 _clutter_stage_presented (stage_cogl->wrapper, frame_event, frame_info);
4953+
4954+ if (frame_event == COGL_FRAME_EVENT_COMPLETE &&
4955+ stage_cogl->update_time != -1)
4956+ {
4957+ ClutterStageWindow *stage_window = CLUTTER_STAGE_WINDOW (stage_cogl);
4958+
4959+ stage_cogl->update_time = -1;
4960+ clutter_stage_cogl_schedule_update (stage_window,
4961+ stage_cogl->last_sync_delay);
4962+ }
4963 }
4964
4965 static gboolean
4966@@ -152,10 +169,15 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
4967 gint64 now;
4968 float refresh_rate;
4969 gint64 refresh_interval;
4970+ int64_t min_render_time_allowed;
4971+ int64_t max_render_time_allowed;
4972+ int64_t next_presentation_time;
4973
4974 if (stage_cogl->update_time != -1)
4975 return;
4976
4977+ stage_cogl->last_sync_delay = sync_delay;
4978+
4979 now = g_get_monotonic_time ();
4980
4981 if (sync_delay < 0)
4982@@ -164,30 +186,56 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
4983 return;
4984 }
4985
4986- /* We only extrapolate presentation times for 150ms - this is somewhat
4987- * arbitrary. The reasons it might not be accurate for larger times are
4988- * that the refresh interval might be wrong or the vertical refresh
4989- * might be downclocked if nothing is going on onscreen.
4990- */
4991- if (stage_cogl->last_presentation_time == 0||
4992- stage_cogl->last_presentation_time < now - 150000)
4993+ refresh_rate = stage_cogl->refresh_rate;
4994+ if (refresh_rate <= 0.0)
4995+ refresh_rate = clutter_get_default_frame_rate ();
4996+
4997+ refresh_interval = (gint64) (0.5 + G_USEC_PER_SEC / refresh_rate);
4998+ if (refresh_interval == 0)
4999 {
5000 stage_cogl->update_time = now;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches